mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'main' into timestamps
This commit is contained in:
Generated
+17
-17
@@ -234,7 +234,7 @@
|
||||
"normalize-path": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
|
||||
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
||||
"integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"remove-trailing-separator": "^1.0.1"
|
||||
@@ -638,9 +638,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "17.0.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz",
|
||||
"integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==",
|
||||
"version": "17.0.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz",
|
||||
"integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node-fetch": {
|
||||
@@ -1964,7 +1964,7 @@
|
||||
"detect-newline": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
|
||||
"integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
|
||||
"integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
@@ -2600,7 +2600,7 @@
|
||||
"event-emitter": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
||||
"integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
|
||||
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"d": "1",
|
||||
@@ -3130,7 +3130,7 @@
|
||||
"get-func-name": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
|
||||
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
|
||||
"integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
|
||||
"dev": true
|
||||
},
|
||||
"get-intrinsic": {
|
||||
@@ -3390,7 +3390,7 @@
|
||||
"gulp-concat": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
|
||||
"integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=",
|
||||
"integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-with-sourcemaps": "^1.0.0",
|
||||
@@ -3401,7 +3401,7 @@
|
||||
"gulp-insert": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-insert/-/gulp-insert-0.5.0.tgz",
|
||||
"integrity": "sha1-MjE/E+SiPPWsylzl8MCAkjx3hgI=",
|
||||
"integrity": "sha512-SDKCWmjomAo0N0Bzj9qEKIfURORJR/72p6AbDBIK9yKZw794ROTrQHliBem+NJzS2GsTWSm8dGWJ5L7KtjnMRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^1.0.26-4",
|
||||
@@ -3411,7 +3411,7 @@
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
@@ -4006,7 +4006,7 @@
|
||||
"kew": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
|
||||
"integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
|
||||
"integrity": "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==",
|
||||
"dev": true
|
||||
},
|
||||
"kind-of": {
|
||||
@@ -4138,7 +4138,7 @@
|
||||
"lru-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
|
||||
"integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
|
||||
"integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es5-ext": "~0.10.2"
|
||||
@@ -4705,7 +4705,7 @@
|
||||
"mocha-fivemat-progress-reporter": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha-fivemat-progress-reporter/-/mocha-fivemat-progress-reporter-0.1.0.tgz",
|
||||
"integrity": "sha1-zK/w4ckc9Vf+d+B535lUuRt0d1Y=",
|
||||
"integrity": "sha512-nCf6dmCEHObJ8BBrcjW+UHYvVtHEL+FliYR/Mfc/v7dKenNmBQ0ZSuvlICgsyQy9Tt581ldvh+SReS4qp4LrQw==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
@@ -4834,7 +4834,7 @@
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true
|
||||
},
|
||||
"object-copy": {
|
||||
@@ -5192,7 +5192,7 @@
|
||||
"extend-shallow": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
|
||||
"integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
|
||||
"integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^1.1.0"
|
||||
@@ -5201,7 +5201,7 @@
|
||||
"kind-of": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
||||
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
||||
"integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -5960,7 +5960,7 @@
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
|
||||
+308
-165
@@ -74,7 +74,7 @@ namespace ts {
|
||||
TypeofNEString = 1 << 8, // typeof x !== "string"
|
||||
TypeofNENumber = 1 << 9, // typeof x !== "number"
|
||||
TypeofNEBigInt = 1 << 10, // typeof x !== "bigint"
|
||||
TypeofNEBoolean = 1 << 11, // typeof x !== "boolean"
|
||||
TypeofNEBoolean = 1 << 11, // typeof x !== "boolean"
|
||||
TypeofNESymbol = 1 << 12, // typeof x !== "symbol"
|
||||
TypeofNEObject = 1 << 13, // typeof x !== "object"
|
||||
TypeofNEFunction = 1 << 14, // typeof x !== "function"
|
||||
@@ -87,7 +87,10 @@ namespace ts {
|
||||
NEUndefinedOrNull = 1 << 21, // x != undefined / x != null
|
||||
Truthy = 1 << 22, // x
|
||||
Falsy = 1 << 23, // !x
|
||||
All = (1 << 24) - 1,
|
||||
IsUndefined = 1 << 24, // Exactly undefined
|
||||
IsNull = 1 << 25, // Exactly null
|
||||
IsUndefinedOrNull = IsUndefined | IsNull,
|
||||
All = (1 << 27) - 1,
|
||||
// The following members encode facts about particular kinds of types for use in the getTypeFacts function.
|
||||
// The presence of a particular fact means that the given test is true for some (and possibly all) values
|
||||
// of that kind of type.
|
||||
@@ -129,11 +132,13 @@ namespace ts {
|
||||
ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
||||
FunctionStrictFacts = TypeofEQFunction | TypeofEQHostObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | NEUndefined | NENull | NEUndefinedOrNull | Truthy,
|
||||
FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
|
||||
UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy,
|
||||
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
|
||||
EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull),
|
||||
VoidFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy,
|
||||
UndefinedFacts = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | TypeofNEHostObject | EQUndefined | EQUndefinedOrNull | NENull | Falsy | IsUndefined,
|
||||
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy | IsNull,
|
||||
EmptyObjectStrictFacts = All & ~(EQUndefined | EQNull | EQUndefinedOrNull | IsUndefinedOrNull),
|
||||
EmptyObjectFacts = All & ~IsUndefinedOrNull,
|
||||
UnknownFacts = All & ~IsUndefinedOrNull,
|
||||
AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined,
|
||||
EmptyObjectFacts = All,
|
||||
// Masks
|
||||
OrFactsMask = TypeofEQFunction | TypeofNEObject,
|
||||
AndFactsMask = All & ~OrFactsMask,
|
||||
@@ -848,6 +853,8 @@ namespace ts {
|
||||
emptyTypeLiteralSymbol.members = createSymbolTable();
|
||||
const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray);
|
||||
|
||||
const unknownUnionType = strictNullChecks ? getUnionType([undefinedType, nullType, createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray)]) : unknownType;
|
||||
|
||||
const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType;
|
||||
emptyGenericType.instantiations = new Map<string, TypeReference>();
|
||||
|
||||
@@ -2476,7 +2483,12 @@ namespace ts {
|
||||
function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
|
||||
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
|
||||
if (isPrimitiveTypeName(name)) {
|
||||
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name));
|
||||
if (isExtendedByInterface(errorLocation)) {
|
||||
error(errorLocation, Diagnostics.An_interface_cannot_extend_a_primitive_type_like_0_an_interface_can_only_extend_named_types_and_classes, unescapeLeadingUnderscores(name));
|
||||
}
|
||||
else {
|
||||
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, unescapeLeadingUnderscores(name));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
@@ -2497,6 +2509,17 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isExtendedByInterface(node: Node): boolean {
|
||||
const grandparent = node.parent.parent;
|
||||
const parentOfGrandparent = grandparent.parent;
|
||||
if(grandparent && parentOfGrandparent){
|
||||
const isExtending = isHeritageClause(grandparent) && grandparent.token === SyntaxKind.ExtendsKeyword;
|
||||
const isInterface = isInterfaceDeclaration(parentOfGrandparent);
|
||||
return isExtending && isInterface;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function maybeMappedType(node: Node, symbol: Symbol) {
|
||||
const container = findAncestor(node.parent, n =>
|
||||
isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined;
|
||||
@@ -5620,7 +5643,7 @@ namespace ts {
|
||||
anyType : getNonMissingTypeOfSymbol(propertySymbol);
|
||||
const saveEnclosingDeclaration = context.enclosingDeclaration;
|
||||
context.enclosingDeclaration = undefined;
|
||||
if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) {
|
||||
if (context.tracker.trackSymbol && isLateBoundName(propertySymbol.escapedName)) {
|
||||
if (propertySymbol.declarations) {
|
||||
const decl = first(propertySymbol.declarations);
|
||||
if (hasLateBindableName(decl)) {
|
||||
@@ -7556,7 +7579,7 @@ namespace ts {
|
||||
...!length(baseTypes) ? [] : [factory.createHeritageClause(SyntaxKind.ExtendsKeyword, map(baseTypes, b => serializeBaseType(b, staticBaseType, localName)))],
|
||||
...!length(implementsExpressions) ? [] : [factory.createHeritageClause(SyntaxKind.ImplementsKeyword, implementsExpressions)]
|
||||
];
|
||||
const symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType));
|
||||
const symbolProps = getNonInheritedProperties(classType, baseTypes, getPropertiesOfType(classType));
|
||||
const publicSymbolProps = filter(symbolProps, s => {
|
||||
// `valueDeclaration` could be undefined if inherited from
|
||||
// a union/intersection base type, but inherited properties
|
||||
@@ -8885,7 +8908,7 @@ namespace ts {
|
||||
if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) {
|
||||
// In strict null checking mode, if a default value of a non-undefined type is specified, remove
|
||||
// undefined from the final type.
|
||||
return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFlags.Undefined) ? getNonUndefinedType(type) : type;
|
||||
return strictNullChecks && !(getTypeFacts(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFacts.IsUndefined) ? getNonUndefinedType(type) : type;
|
||||
}
|
||||
return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type), checkDeclarationInitializer(declaration, CheckMode.Normal)], UnionReduction.Subtype));
|
||||
}
|
||||
@@ -12058,7 +12081,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t.flags & TypeFlags.DisjointDomains) {
|
||||
else if (t.flags & TypeFlags.DisjointDomains || isEmptyAnonymousObjectType(t)) {
|
||||
hasDisjointDomainType = true;
|
||||
}
|
||||
}
|
||||
@@ -12069,7 +12092,7 @@ namespace ts {
|
||||
// We add any types belong to one of the disjoint domains because they might cause the final
|
||||
// intersection operation to reduce the union constraints.
|
||||
for (const t of types) {
|
||||
if (t.flags & TypeFlags.DisjointDomains) {
|
||||
if (t.flags & TypeFlags.DisjointDomains || isEmptyAnonymousObjectType(t)) {
|
||||
constraints = append(constraints, t);
|
||||
}
|
||||
}
|
||||
@@ -12285,7 +12308,7 @@ namespace ts {
|
||||
let objectType;
|
||||
return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped &&
|
||||
!isGenericMappedType(objectType) && isGenericIndexType((type as IndexedAccessType).indexType) &&
|
||||
!(objectType as MappedType).declaration.questionToken && !(objectType as MappedType).declaration.nameType);
|
||||
!(getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.ExcludeOptional) && !(objectType as MappedType).declaration.nameType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -14826,7 +14849,7 @@ namespace ts {
|
||||
return includes;
|
||||
}
|
||||
|
||||
function removeRedundantPrimitiveTypes(types: Type[], includes: TypeFlags) {
|
||||
function removeRedundantSupertypes(types: Type[], includes: TypeFlags) {
|
||||
let i = types.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
@@ -14835,7 +14858,9 @@ namespace ts {
|
||||
t.flags & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ||
|
||||
t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
||||
t.flags & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
||||
t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol;
|
||||
t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol ||
|
||||
t.flags & TypeFlags.Void && includes & TypeFlags.Undefined ||
|
||||
isEmptyAnonymousObjectType(t) && includes & TypeFlags.DefinitelyNonNullable;
|
||||
if (remove) {
|
||||
orderedRemoveItemAt(types, i);
|
||||
}
|
||||
@@ -14959,7 +14984,7 @@ namespace ts {
|
||||
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
|
||||
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
|
||||
// for intersections of types with signatures can be deterministic.
|
||||
function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
|
||||
function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], noSupertypeReduction?: boolean): Type {
|
||||
const typeMembershipMap: ESMap<string, Type> = new Map();
|
||||
const includes = addTypesToIntersection(typeMembershipMap, 0, types);
|
||||
const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
|
||||
@@ -14996,11 +15021,10 @@ namespace ts {
|
||||
if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ||
|
||||
includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
||||
includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
||||
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
|
||||
removeRedundantPrimitiveTypes(typeSet, includes);
|
||||
}
|
||||
if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) {
|
||||
orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType));
|
||||
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol ||
|
||||
includes & TypeFlags.Void && includes & TypeFlags.Undefined ||
|
||||
includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.DefinitelyNonNullable) {
|
||||
if (!noSupertypeReduction) removeRedundantSupertypes(typeSet, includes);
|
||||
}
|
||||
if (includes & TypeFlags.IncludesMissingType) {
|
||||
typeSet[typeSet.indexOf(undefinedType)] = missingType;
|
||||
@@ -15039,8 +15063,9 @@ namespace ts {
|
||||
}
|
||||
const constituents = getCrossProductIntersections(typeSet);
|
||||
// We attach a denormalized origin type when at least one constituent of the cross-product union is an
|
||||
// intersection (i.e. when the intersection didn't just reduce one or more unions to smaller unions).
|
||||
const origin = some(constituents, t => !!(t.flags & TypeFlags.Intersection)) ? createOriginUnionOrIntersectionType(TypeFlags.Intersection, typeSet) : undefined;
|
||||
// intersection (i.e. when the intersection didn't just reduce one or more unions to smaller unions) and
|
||||
// the denormalized origin has fewer constituents than the union itself.
|
||||
const origin = some(constituents, t => !!(t.flags & TypeFlags.Intersection)) && getConstituentCountOfTypes(constituents) > getConstituentCountOfTypes(typeSet) ? createOriginUnionOrIntersectionType(TypeFlags.Intersection, typeSet) : undefined;
|
||||
result = getUnionType(constituents, UnionReduction.Literal, aliasSymbol, aliasTypeArguments, origin);
|
||||
}
|
||||
}
|
||||
@@ -15086,12 +15111,23 @@ namespace ts {
|
||||
return intersections;
|
||||
}
|
||||
|
||||
function getConstituentCount(type: Type): number {
|
||||
return !(type.flags & TypeFlags.UnionOrIntersection) || type.aliasSymbol ? 1 :
|
||||
type.flags & TypeFlags.Union && (type as UnionType).origin ? getConstituentCount((type as UnionType).origin!) :
|
||||
getConstituentCountOfTypes((type as UnionOrIntersectionType).types);
|
||||
}
|
||||
|
||||
function getConstituentCountOfTypes(types: Type[]): number {
|
||||
return reduceLeft(types, (n, t) => n + getConstituentCount(t), 0);
|
||||
}
|
||||
|
||||
function getTypeFromIntersectionTypeNode(node: IntersectionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const aliasSymbol = getAliasSymbolForTypeNode(node);
|
||||
links.resolvedType = getIntersectionType(map(node.types, getTypeFromTypeNode),
|
||||
aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
|
||||
const types = map(node.types, getTypeFromTypeNode);
|
||||
const noSupertypeReduction = types.length === 2 && !!(types[0].flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt)) && types[1] === emptyTypeLiteralType;
|
||||
links.resolvedType = getIntersectionType(types, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol), noSupertypeReduction);
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -17981,7 +18017,7 @@ namespace ts {
|
||||
const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
|
||||
const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType));
|
||||
const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) &&
|
||||
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
|
||||
(getTypeFacts(sourceType) & TypeFacts.IsUndefinedOrNull) === (getTypeFacts(targetType) & TypeFacts.IsUndefinedOrNull);
|
||||
let related = callbacks ?
|
||||
compareSignaturesRelated(targetSig, sourceSig, (checkMode & SignatureCheckMode.StrictArity) | (strictVariance ? SignatureCheckMode.StrictCallback : SignatureCheckMode.BivariantCallback), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) :
|
||||
!(checkMode & SignatureCheckMode.Callback) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
|
||||
@@ -18116,6 +18152,18 @@ namespace ts {
|
||||
type.symbol && type.symbol.flags & SymbolFlags.TypeLiteral && getMembersOfSymbol(type.symbol).size === 0));
|
||||
}
|
||||
|
||||
function isUnknownLikeUnionType(type: Type) {
|
||||
if (strictNullChecks && type.flags & TypeFlags.Union) {
|
||||
if (!((type as UnionType).objectFlags & ObjectFlags.IsUnknownLikeUnionComputed)) {
|
||||
const types = (type as UnionType).types;
|
||||
(type as UnionType).objectFlags |= ObjectFlags.IsUnknownLikeUnionComputed | (types.length >= 3 && types[0].flags & TypeFlags.Undefined &&
|
||||
types[1].flags & TypeFlags.Null && some(types, isEmptyAnonymousObjectType) ? ObjectFlags.IsUnknownLikeUnion : 0);
|
||||
}
|
||||
return !!((type as UnionType).objectFlags & ObjectFlags.IsUnknownLikeUnion);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isStringIndexSignatureOnlyType(type: Type): boolean {
|
||||
return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, stringType) ||
|
||||
type.flags & TypeFlags.UnionOrIntersection && every((type as UnionOrIntersectionType).types, isStringIndexSignatureOnlyType) ||
|
||||
@@ -18183,7 +18231,7 @@ namespace ts {
|
||||
// Since unions and intersections may reduce to `never`, we exclude them here.
|
||||
if (s & TypeFlags.Undefined && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
|
||||
if (s & TypeFlags.Null && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & TypeFlags.Null)) return true;
|
||||
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true;
|
||||
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(relation === strictSubtypeRelation && isEmptyAnonymousObjectType(source))) return true;
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (s & TypeFlags.Any) return true;
|
||||
// Type number or any numeric literal type is assignable to any numeric enum type or any
|
||||
@@ -18191,6 +18239,8 @@ namespace ts {
|
||||
// bit-flag enum types sometimes look like literal enum types with numeric literal values.
|
||||
if (s & (TypeFlags.Number | TypeFlags.NumberLiteral) && !(s & TypeFlags.EnumLiteral) && (
|
||||
t & TypeFlags.Enum || relation === assignableRelation && t & TypeFlags.NumberLiteral && t & TypeFlags.EnumLiteral)) return true;
|
||||
// Anything is assignable to a union containing undefined, null, and {}
|
||||
if (isUnknownLikeUnionType(target)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -18233,16 +18283,28 @@ namespace ts {
|
||||
|
||||
function getNormalizedType(type: Type, writing: boolean): Type {
|
||||
while (true) {
|
||||
let t = isFreshLiteralType(type) ? (type as FreshableType).regularType :
|
||||
getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node ? createTypeReference((type as TypeReference).target, getTypeArguments(type as TypeReference)) :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? getReducedType(type) :
|
||||
const t = isFreshLiteralType(type) ? (type as FreshableType).regularType :
|
||||
getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).node ? createTypeReference((type as TypeReference).target, getTypeArguments(type as TypeReference)) : getSingleBaseForNonAugmentingSubtype(type) || type :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? getNormalizedUnionOrIntersectionType(type as UnionOrIntersectionType, writing) :
|
||||
type.flags & TypeFlags.Substitution ? writing ? (type as SubstitutionType).baseType : (type as SubstitutionType).substitute :
|
||||
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
|
||||
type;
|
||||
t = getSingleBaseForNonAugmentingSubtype(t) || t;
|
||||
if (t === type) break;
|
||||
if (t === type) return t;
|
||||
type = t;
|
||||
}
|
||||
}
|
||||
|
||||
function getNormalizedUnionOrIntersectionType(type: UnionOrIntersectionType, writing: boolean) {
|
||||
const reduced = getReducedType(type);
|
||||
if (reduced !== type) {
|
||||
return reduced;
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
const normalizedTypes = sameMap(type.types, t => getNormalizedType(t, writing));
|
||||
if (normalizedTypes !== type.types) {
|
||||
return getIntersectionType(normalizedTypes);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -18772,6 +18834,9 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
reportRelationError(headMessage, source, target);
|
||||
if (strictNullChecks && source.flags & TypeFlags.TypeVariable && source.symbol?.declarations?.[0] && !getConstraintOfType(source as TypeVariable) && isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
|
||||
associateRelatedInfo(createDiagnosticForNode(source.symbol.declarations[0], Diagnostics.This_type_parameter_probably_needs_an_extends_object_constraint));
|
||||
}
|
||||
}
|
||||
|
||||
function traceUnionsOrIntersectionsTooLarge(source: Type, target: Type): void {
|
||||
@@ -19576,13 +19641,6 @@ namespace ts {
|
||||
// IndexedAccess comparisons are handled above in the `targetFlags & TypeFlage.IndexedAccess` branch
|
||||
if (!(sourceFlags & TypeFlags.IndexedAccess && targetFlags & TypeFlags.IndexedAccess)) {
|
||||
const constraint = getConstraintOfType(source as TypeVariable) || unknownType;
|
||||
if (!getConstraintOfType(source as TypeVariable) || (sourceFlags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
|
||||
// A type variable with no constraint is not related to the non-primitive object type.
|
||||
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive), RecursionFlags.Both)) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
|
||||
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
@@ -21106,9 +21164,11 @@ namespace ts {
|
||||
return getSupertypeOrUnion(types);
|
||||
}
|
||||
const primaryTypes = filter(types, t => !(t.flags & TypeFlags.Nullable));
|
||||
return primaryTypes.length ?
|
||||
getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & TypeFlags.Nullable) :
|
||||
getUnionType(types, UnionReduction.Subtype);
|
||||
if (primaryTypes.length) {
|
||||
const supertypeOrUnion = getSupertypeOrUnion(primaryTypes);
|
||||
return primaryTypes === types ? supertypeOrUnion : getUnionType([supertypeOrUnion, ...filter(types, t => !!(t.flags & TypeFlags.Nullable))]);
|
||||
}
|
||||
return getUnionType(types, UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
// Return the leftmost type for which no type to the right is a subtype.
|
||||
@@ -21325,30 +21385,8 @@ namespace ts {
|
||||
return value.base10Value === "0";
|
||||
}
|
||||
|
||||
function getFalsyFlagsOfTypes(types: Type[]): TypeFlags {
|
||||
let result: TypeFlags = 0;
|
||||
for (const t of types) {
|
||||
result |= getFalsyFlags(t);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
|
||||
// flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
|
||||
// no flags for all other types (including non-falsy literal types).
|
||||
function getFalsyFlags(type: Type): TypeFlags {
|
||||
return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type as UnionType).types) :
|
||||
type.flags & TypeFlags.StringLiteral ? (type as StringLiteralType).value === "" ? TypeFlags.StringLiteral : 0 :
|
||||
type.flags & TypeFlags.NumberLiteral ? (type as NumberLiteralType).value === 0 ? TypeFlags.NumberLiteral : 0 :
|
||||
type.flags & TypeFlags.BigIntLiteral ? isZeroBigInt(type as BigIntLiteralType) ? TypeFlags.BigIntLiteral : 0 :
|
||||
type.flags & TypeFlags.BooleanLiteral ? (type === falseType || type === regularFalseType) ? TypeFlags.BooleanLiteral : 0 :
|
||||
type.flags & TypeFlags.PossiblyFalsy;
|
||||
}
|
||||
|
||||
function removeDefinitelyFalsyTypes(type: Type): Type {
|
||||
return getFalsyFlags(type) & TypeFlags.DefinitelyFalsy ?
|
||||
filterType(type, t => !(getFalsyFlags(t) & TypeFlags.DefinitelyFalsy)) :
|
||||
type;
|
||||
return filterType(type, t => !!(getTypeFacts(t) & TypeFacts.Truthy));
|
||||
}
|
||||
|
||||
function extractDefinitelyFalsyTypes(type: Type): Type {
|
||||
@@ -21387,21 +21425,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getGlobalNonNullableTypeInstantiation(type: Type) {
|
||||
// First reduce away any constituents that are assignable to 'undefined' or 'null'. This not only eliminates
|
||||
// 'undefined' and 'null', but also higher-order types such as a type parameter 'U extends undefined | null'
|
||||
// that isn't eliminated by a NonNullable<T> instantiation.
|
||||
const reducedType = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
if (!deferredGlobalNonNullableTypeAlias) {
|
||||
deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable" as __String, SymbolFlags.TypeAlias, /*diagnostic*/ undefined) || unknownSymbol;
|
||||
}
|
||||
// If the NonNullable<T> type is available, return an instantiation. Otherwise just return the reduced type.
|
||||
return deferredGlobalNonNullableTypeAlias !== unknownSymbol ?
|
||||
getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [reducedType]) :
|
||||
reducedType;
|
||||
getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [type]) :
|
||||
getIntersectionType([type, emptyObjectType]);
|
||||
}
|
||||
|
||||
function getNonNullableType(type: Type): Type {
|
||||
return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
|
||||
return strictNullChecks ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
|
||||
function addOptionalTypeMarker(type: Type) {
|
||||
@@ -22112,13 +22145,40 @@ namespace ts {
|
||||
sourceEnd.slice(sourceEnd.length - endLen) !== targetEnd.slice(targetEnd.length - endLen);
|
||||
}
|
||||
|
||||
function isValidBigIntString(s: string): boolean {
|
||||
/**
|
||||
* Tests whether the provided string can be parsed as a number.
|
||||
* @param s The string to test.
|
||||
* @param roundTripOnly Indicates the resulting number matches the input when converted back to a string.
|
||||
*/
|
||||
function isValidNumberString(s: string, roundTripOnly: boolean): boolean {
|
||||
if (s === "") return false;
|
||||
const n = +s;
|
||||
return isFinite(n) && (!roundTripOnly || "" + n === s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text a valid bigint string excluding a trailing `n`, but including a possible prefix `-`. Use `isValidBigIntString(text, roundTripOnly)` before calling this function.
|
||||
*/
|
||||
function parseBigIntLiteralType(text: string) {
|
||||
const negative = text.startsWith("-");
|
||||
const base10Value = parsePseudoBigInt(`${negative ? text.slice(1) : text}n`);
|
||||
return getBigIntLiteralType({ negative, base10Value });
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the provided string can be parsed as a bigint.
|
||||
* @param s The string to test.
|
||||
* @param roundTripOnly Indicates the resulting bigint matches the input when converted back to a string.
|
||||
*/
|
||||
function isValidBigIntString(s: string, roundTripOnly: boolean): boolean {
|
||||
if (s === "") return false;
|
||||
const scanner = createScanner(ScriptTarget.ESNext, /*skipTrivia*/ false);
|
||||
let success = true;
|
||||
scanner.setOnError(() => success = false);
|
||||
scanner.setText(s + "n");
|
||||
let result = scanner.scan();
|
||||
if (result === SyntaxKind.MinusToken) {
|
||||
const negative = result === SyntaxKind.MinusToken;
|
||||
if (negative) {
|
||||
result = scanner.scan();
|
||||
}
|
||||
const flags = scanner.getTokenFlags();
|
||||
@@ -22127,7 +22187,8 @@ namespace ts {
|
||||
// * a bigint can be scanned, and that when it is scanned, it is
|
||||
// * the full length of the input string (so the scanner is one character beyond the augmented input length)
|
||||
// * it does not contain a numeric seperator (the `BigInt` constructor does not accept a numeric seperator in its input)
|
||||
return success && result === SyntaxKind.BigIntLiteral && scanner.getTextPos() === (s.length + 1) && !(flags & TokenFlags.ContainsSeparator);
|
||||
return success && result === SyntaxKind.BigIntLiteral && scanner.getTextPos() === (s.length + 1) && !(flags & TokenFlags.ContainsSeparator)
|
||||
&& (!roundTripOnly || s === pseudoBigIntToString({ negative, base10Value: parsePseudoBigInt(scanner.getTokenValue()) }));
|
||||
}
|
||||
|
||||
function isValidTypeForTemplateLiteralPlaceholder(source: Type, target: Type): boolean {
|
||||
@@ -22136,8 +22197,8 @@ namespace ts {
|
||||
}
|
||||
if (source.flags & TypeFlags.StringLiteral) {
|
||||
const value = (source as StringLiteralType).value;
|
||||
return !!(target.flags & TypeFlags.Number && value !== "" && isFinite(+value) ||
|
||||
target.flags & TypeFlags.BigInt && value !== "" && isValidBigIntString(value) ||
|
||||
return !!(target.flags & TypeFlags.Number && isValidNumberString(value, /*roundTripOnly*/ false) ||
|
||||
target.flags & TypeFlags.BigInt && isValidBigIntString(value, /*roundTripOnly*/ false) ||
|
||||
target.flags & (TypeFlags.BooleanLiteral | TypeFlags.Nullable) && value === (target as IntrinsicType).intrinsicName);
|
||||
}
|
||||
if (source.flags & TypeFlags.TemplateLiteral) {
|
||||
@@ -22715,7 +22776,60 @@ namespace ts {
|
||||
// succeed. That would be a pointless and confusing outcome.
|
||||
if (matches || every(target.texts, s => s.length === 0)) {
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
inferFromTypes(matches ? matches[i] : neverType, types[i]);
|
||||
const source = matches ? matches[i] : neverType;
|
||||
const target = types[i];
|
||||
|
||||
// If we are inferring from a string literal type to a type variable whose constraint includes one of the
|
||||
// allowed template literal placeholder types, infer from a literal type corresponding to the constraint.
|
||||
if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.TypeVariable) {
|
||||
const inferenceContext = getInferenceInfoForType(target);
|
||||
const constraint = inferenceContext ? getBaseConstraintOfType(inferenceContext.typeParameter) : undefined;
|
||||
if (constraint && !isTypeAny(constraint)) {
|
||||
const constraintTypes = constraint.flags & TypeFlags.Union ? (constraint as UnionType).types : [constraint];
|
||||
let allTypeFlags: TypeFlags = reduceLeft(constraintTypes, (flags, t) => flags | t.flags, 0 as TypeFlags);
|
||||
|
||||
// If the constraint contains `string`, we don't need to look for a more preferred type
|
||||
if (!(allTypeFlags & TypeFlags.String)) {
|
||||
const str = (source as StringLiteralType).value;
|
||||
|
||||
// If the type contains `number` or a number literal and the string isn't a valid number, exclude numbers
|
||||
if (allTypeFlags & TypeFlags.NumberLike && !isValidNumberString(str, /*roundTripOnly*/ true)) {
|
||||
allTypeFlags &= ~TypeFlags.NumberLike;
|
||||
}
|
||||
|
||||
// If the type contains `bigint` or a bigint literal and the string isn't a valid bigint, exclude bigints
|
||||
if (allTypeFlags & TypeFlags.BigIntLike && !isValidBigIntString(str, /*roundTripOnly*/ true)) {
|
||||
allTypeFlags &= ~TypeFlags.BigIntLike;
|
||||
}
|
||||
|
||||
// for each type in the constraint, find the highest priority matching type
|
||||
const matchingType = reduceLeft(constraintTypes, (left, right) =>
|
||||
!(right.flags & allTypeFlags) ? left :
|
||||
left.flags & TypeFlags.String ? left : right.flags & TypeFlags.String ? source :
|
||||
left.flags & TypeFlags.TemplateLiteral ? left : right.flags & TypeFlags.TemplateLiteral && isTypeMatchedByTemplateLiteralType(source, right as TemplateLiteralType) ? source :
|
||||
left.flags & TypeFlags.StringMapping ? left : right.flags & TypeFlags.StringMapping && str === applyStringMapping(right.symbol, str) ? source :
|
||||
left.flags & TypeFlags.StringLiteral ? left : right.flags & TypeFlags.StringLiteral && (right as StringLiteralType).value === str ? right :
|
||||
left.flags & TypeFlags.Number ? left : right.flags & TypeFlags.Number ? getNumberLiteralType(+str) :
|
||||
left.flags & TypeFlags.Enum ? left : right.flags & TypeFlags.Enum ? getNumberLiteralType(+str) :
|
||||
left.flags & TypeFlags.NumberLiteral ? left : right.flags & TypeFlags.NumberLiteral && (right as NumberLiteralType).value === +str ? right :
|
||||
left.flags & TypeFlags.BigInt ? left : right.flags & TypeFlags.BigInt ? parseBigIntLiteralType(str) :
|
||||
left.flags & TypeFlags.BigIntLiteral ? left : right.flags & TypeFlags.BigIntLiteral && pseudoBigIntToString((right as BigIntLiteralType).value) === str ? right :
|
||||
left.flags & TypeFlags.Boolean ? left : right.flags & TypeFlags.Boolean ? str === "true" ? trueType : str === "false" ? falseType : booleanType :
|
||||
left.flags & TypeFlags.BooleanLiteral ? left : right.flags & TypeFlags.BooleanLiteral && (right as IntrinsicType).intrinsicName === str ? right :
|
||||
left.flags & TypeFlags.Undefined ? left : right.flags & TypeFlags.Undefined && (right as IntrinsicType).intrinsicName === str ? right :
|
||||
left.flags & TypeFlags.Null ? left : right.flags & TypeFlags.Null && (right as IntrinsicType).intrinsicName === str ? right :
|
||||
left,
|
||||
neverType as Type);
|
||||
|
||||
if (!(matchingType.flags & TypeFlags.Never)) {
|
||||
inferFromTypes(matchingType, target);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inferFromTypes(source, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23410,13 +23524,16 @@ namespace ts {
|
||||
resolved.members.get("bind" as __String) && isTypeSubtypeOf(type, globalFunctionType));
|
||||
}
|
||||
|
||||
function getTypeFacts(type: Type, ignoreObjects = false): TypeFacts {
|
||||
function getTypeFacts(type: Type): TypeFacts {
|
||||
if (type.flags & (TypeFlags.Intersection | TypeFlags.Instantiable)) {
|
||||
type = getBaseConstraintOfType(type) || unknownType;
|
||||
}
|
||||
const flags = type.flags;
|
||||
if (flags & TypeFlags.String) {
|
||||
if (flags & (TypeFlags.String | TypeFlags.StringMapping)) {
|
||||
return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts;
|
||||
}
|
||||
if (flags & TypeFlags.StringLiteral) {
|
||||
const isEmpty = (type as StringLiteralType).value === "";
|
||||
if (flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral)) {
|
||||
const isEmpty = flags & TypeFlags.StringLiteral && (type as StringLiteralType).value === "";
|
||||
return strictNullChecks ?
|
||||
isEmpty ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts :
|
||||
isEmpty ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts;
|
||||
@@ -23448,16 +23565,16 @@ namespace ts {
|
||||
(type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Object) {
|
||||
if (ignoreObjects) {
|
||||
return TypeFacts.AndFactsMask; // This is the identity element for computing type facts of intersection.
|
||||
}
|
||||
return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type as ObjectType) ?
|
||||
strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts :
|
||||
isFunctionObjectType(type as ObjectType) ?
|
||||
strictNullChecks ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts :
|
||||
strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
|
||||
}
|
||||
if (flags & (TypeFlags.Void | TypeFlags.Undefined)) {
|
||||
if (flags & TypeFlags.Void) {
|
||||
return TypeFacts.VoidFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Undefined) {
|
||||
return TypeFacts.UndefinedFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Null) {
|
||||
@@ -23472,31 +23589,29 @@ namespace ts {
|
||||
if (flags & TypeFlags.Never) {
|
||||
return TypeFacts.None;
|
||||
}
|
||||
if (flags & TypeFlags.Instantiable) {
|
||||
return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType, ignoreObjects) :
|
||||
strictNullChecks ? TypeFacts.NonEmptyStringStrictFacts : TypeFacts.NonEmptyStringFacts;
|
||||
}
|
||||
if (flags & TypeFlags.Union) {
|
||||
return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t, ignoreObjects), TypeFacts.None);
|
||||
return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t), TypeFacts.None);
|
||||
}
|
||||
if (flags & TypeFlags.Intersection) {
|
||||
// When an intersection contains a primitive type we ignore object type constituents as they are
|
||||
// presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type.
|
||||
ignoreObjects ||= maybeTypeOfKind(type, TypeFlags.Primitive);
|
||||
return getIntersectionTypeFacts(type as IntersectionType, ignoreObjects);
|
||||
return getIntersectionTypeFacts(type as IntersectionType);
|
||||
}
|
||||
return TypeFacts.All;
|
||||
return TypeFacts.UnknownFacts;
|
||||
}
|
||||
|
||||
function getIntersectionTypeFacts(type: IntersectionType, ignoreObjects: boolean): TypeFacts {
|
||||
function getIntersectionTypeFacts(type: IntersectionType): TypeFacts {
|
||||
// When an intersection contains a primitive type we ignore object type constituents as they are
|
||||
// presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type.
|
||||
const ignoreObjects = maybeTypeOfKind(type, TypeFlags.Primitive);
|
||||
// When computing the type facts of an intersection type, certain type facts are computed as `and`
|
||||
// and others are computed as `or`.
|
||||
let oredFacts = TypeFacts.None;
|
||||
let andedFacts = TypeFacts.All;
|
||||
for (const t of type.types) {
|
||||
const f = getTypeFacts(t, ignoreObjects);
|
||||
oredFacts |= f;
|
||||
andedFacts &= f;
|
||||
if (!(ignoreObjects && t.flags & TypeFlags.Object)) {
|
||||
const f = getTypeFacts(t);
|
||||
oredFacts |= f;
|
||||
andedFacts &= f;
|
||||
}
|
||||
}
|
||||
return oredFacts & TypeFacts.OrFactsMask | andedFacts & TypeFacts.AndFactsMask;
|
||||
}
|
||||
@@ -23505,6 +23620,29 @@ namespace ts {
|
||||
return filterType(type, t => (getTypeFacts(t) & include) !== 0);
|
||||
}
|
||||
|
||||
// This function is similar to getTypeWithFacts, except that in strictNullChecks mode it replaces type
|
||||
// unknown with the union {} | null | undefined (and reduces that accordingly), and it intersects remaining
|
||||
// instantiable types with {}, {} | null, or {} | undefined in order to remove null and/or undefined.
|
||||
function getAdjustedTypeWithFacts(type: Type, facts: TypeFacts) {
|
||||
const reduced = recombineUnknownType(getTypeWithFacts(strictNullChecks && type.flags & TypeFlags.Unknown ? unknownUnionType : type, facts));
|
||||
if (strictNullChecks) {
|
||||
switch (facts) {
|
||||
case TypeFacts.NEUndefined:
|
||||
return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQUndefined ? getIntersectionType([t, getTypeFacts(t) & TypeFacts.EQNull && !maybeTypeOfKind(reduced, TypeFlags.Null) ? getUnionType([emptyObjectType, nullType]) : emptyObjectType]): t);
|
||||
case TypeFacts.NENull:
|
||||
return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQNull ? getIntersectionType([t, getTypeFacts(t) & TypeFacts.EQUndefined && !maybeTypeOfKind(reduced, TypeFlags.Undefined) ? getUnionType([emptyObjectType, undefinedType]) : emptyObjectType]): t);
|
||||
case TypeFacts.NEUndefinedOrNull:
|
||||
case TypeFacts.Truthy:
|
||||
return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQUndefinedOrNull ? getGlobalNonNullableTypeInstantiation(t): t);
|
||||
}
|
||||
}
|
||||
return reduced;
|
||||
}
|
||||
|
||||
function recombineUnknownType(type: Type) {
|
||||
return type === unknownUnionType ? unknownType : type;
|
||||
}
|
||||
|
||||
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
|
||||
return defaultExpression ?
|
||||
getUnionType([getNonUndefinedType(type), getTypeOfExpression(defaultExpression)]) :
|
||||
@@ -24636,7 +24774,7 @@ namespace ts {
|
||||
if (isEvolvingArrayTypeList(types)) {
|
||||
return getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType)));
|
||||
}
|
||||
const result = getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
|
||||
const result = recombineUnknownType(getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction));
|
||||
if (result !== declaredType && result.flags & declaredType.flags & TypeFlags.Union && arraysEqual((result as UnionType).types, (declaredType as UnionType).types)) {
|
||||
return declaredType;
|
||||
}
|
||||
@@ -24744,11 +24882,10 @@ namespace ts {
|
||||
|
||||
function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
||||
if (isMatchingReference(reference, expr)) {
|
||||
return type.flags & TypeFlags.Unknown && assumeTrue ? nonNullUnknownType :
|
||||
getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy);
|
||||
return getAdjustedTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy);
|
||||
}
|
||||
if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) {
|
||||
type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
const access = getDiscriminantPropertyAccess(expr, type);
|
||||
if (access) {
|
||||
@@ -24894,7 +25031,7 @@ namespace ts {
|
||||
// Note that we include any and unknown in the exclusion test because their domain includes null and undefined.
|
||||
const removeNullable = equalsOperator !== assumeTrue && everyType(valueType, t => !!(t.flags & nullableFlags)) ||
|
||||
equalsOperator === assumeTrue && everyType(valueType, t => !(t.flags & (TypeFlags.AnyOrUnknown | nullableFlags)));
|
||||
return removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
return removeNullable ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
|
||||
function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type {
|
||||
@@ -24905,9 +25042,6 @@ namespace ts {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const valueType = getTypeOfExpression(value);
|
||||
if (assumeTrue && (type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken) && (valueType.flags & TypeFlags.Null)) {
|
||||
return getUnionType([nullType, undefinedType]);
|
||||
}
|
||||
if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) {
|
||||
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) {
|
||||
return valueType;
|
||||
@@ -24927,7 +25061,7 @@ namespace ts {
|
||||
valueType.flags & TypeFlags.Null ?
|
||||
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
|
||||
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
|
||||
return type.flags & TypeFlags.Unknown && facts & (TypeFacts.NENull | TypeFacts.NEUndefinedOrNull) ? nonNullUnknownType : getTypeWithFacts(type, facts);
|
||||
return getAdjustedTypeWithFacts(type, facts);
|
||||
}
|
||||
if (assumeTrue) {
|
||||
const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ?
|
||||
@@ -24949,24 +25083,18 @@ namespace ts {
|
||||
const target = getReferenceCandidate(typeOfExpr.expression);
|
||||
if (!isMatchingReference(reference, target)) {
|
||||
if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Any && literal.text === "function") {
|
||||
return type;
|
||||
}
|
||||
if (assumeTrue && type.flags & TypeFlags.Unknown && literal.text === "object") {
|
||||
// The non-null unknown type is used to track whether a previous narrowing operation has removed the null type
|
||||
// from the unknown type. For example, the expression `x && typeof x === 'object'` first narrows x to the non-null
|
||||
// unknown type, and then narrows that to the non-primitive type.
|
||||
return type === nonNullUnknownType ? nonPrimitiveType : getUnionType([nonPrimitiveType, nullType]);
|
||||
}
|
||||
const facts = assumeTrue ?
|
||||
typeofEQFacts.get(literal.text) || TypeFacts.TypeofEQHostObject :
|
||||
typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject;
|
||||
const impliedType = getImpliedTypeFromTypeofGuard(type, literal.text);
|
||||
return getTypeWithFacts(assumeTrue && impliedType ? mapType(type, narrowUnionMemberByTypeof(impliedType)) : type, facts);
|
||||
return getTypeWithFacts(assumeTrue && impliedType ? narrowTypeByImpliedType(type, impliedType) : type, facts);
|
||||
}
|
||||
|
||||
function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) {
|
||||
@@ -25019,10 +25147,10 @@ namespace ts {
|
||||
|
||||
function getImpliedTypeFromTypeofGuard(type: Type, text: string) {
|
||||
switch (text) {
|
||||
case "object":
|
||||
return type.flags & TypeFlags.Any ? type : getUnionType([nullType, nonPrimitiveType]);
|
||||
case "function":
|
||||
return type.flags & TypeFlags.Any ? type : globalFunctionType;
|
||||
case "object":
|
||||
return type.flags & TypeFlags.Unknown ? getUnionType([nonPrimitiveType, nullType]) : type;
|
||||
default:
|
||||
return typeofTypesByName.get(text);
|
||||
}
|
||||
@@ -25034,22 +25162,27 @@ namespace ts {
|
||||
// the guard. For example: narrowing `{} | undefined` by `"boolean"` should produce the type `boolean`, not
|
||||
// the filtered type `{}`. For this reason we narrow constituents of the union individually, in addition to
|
||||
// filtering by type-facts.
|
||||
function narrowUnionMemberByTypeof(candidate: Type) {
|
||||
return (type: Type) => {
|
||||
if (isTypeSubtypeOf(type, candidate)) {
|
||||
return type;
|
||||
function narrowTypeByImpliedType(type: Type, candidate: Type) {
|
||||
if (type.flags & TypeFlags.AnyOrUnknown) {
|
||||
return candidate;
|
||||
}
|
||||
return mapType(type, t => {
|
||||
if (isTypeRelatedTo(t, candidate, strictSubtypeRelation)) {
|
||||
return t;
|
||||
}
|
||||
if (isTypeSubtypeOf(candidate, type)) {
|
||||
return candidate;
|
||||
}
|
||||
if (type.flags & TypeFlags.Instantiable) {
|
||||
const constraint = getBaseConstraintOfType(type) || anyType;
|
||||
if (isTypeSubtypeOf(candidate, constraint)) {
|
||||
return getIntersectionType([type, candidate]);
|
||||
return mapType(candidate, c => {
|
||||
if (!areTypesComparable(t, c)) {
|
||||
return neverType;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
};
|
||||
if (c.flags & TypeFlags.Primitive && t.flags & TypeFlags.Object && !isEmptyAnonymousObjectType(t)) {
|
||||
return isTypeSubtypeOf(c, t) ? c : neverType;
|
||||
}
|
||||
if (c === globalFunctionType && isTypeSubtypeOf(c, t)) {
|
||||
return c;
|
||||
}
|
||||
return getIntersectionType([t, c]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function narrowBySwitchOnTypeOf(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): Type {
|
||||
@@ -25109,7 +25242,7 @@ namespace ts {
|
||||
because it is caught in the first clause.
|
||||
*/
|
||||
const impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => getImpliedTypeFromTypeofGuard(type, text) || type)), switchFacts);
|
||||
return getTypeWithFacts(mapType(type, narrowUnionMemberByTypeof(impliedType)), switchFacts);
|
||||
return getTypeWithFacts(narrowTypeByImpliedType(type, impliedType), switchFacts);
|
||||
}
|
||||
|
||||
function isMatchingConstructorReference(expr: Expression) {
|
||||
@@ -25170,7 +25303,7 @@ namespace ts {
|
||||
const left = getReferenceCandidate(expr.left);
|
||||
if (!isMatchingReference(reference, left)) {
|
||||
if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -25267,7 +25400,7 @@ namespace ts {
|
||||
}
|
||||
if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) &&
|
||||
!(getTypeFacts(predicate.type) & TypeFacts.EQUndefined)) {
|
||||
type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
const access = getDiscriminantPropertyAccess(predicateArgument, type);
|
||||
if (access) {
|
||||
@@ -25326,7 +25459,7 @@ namespace ts {
|
||||
|
||||
function narrowTypeByOptionality(type: Type, expr: Expression, assumePresent: boolean): Type {
|
||||
if (isMatchingReference(reference, expr)) {
|
||||
return getTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull);
|
||||
return getAdjustedTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull);
|
||||
}
|
||||
const access = getDiscriminantPropertyAccess(expr, type);
|
||||
if (access) {
|
||||
@@ -25418,8 +25551,8 @@ namespace ts {
|
||||
const annotationIncludesUndefined = strictNullChecks &&
|
||||
declaration.kind === SyntaxKind.Parameter &&
|
||||
declaration.initializer &&
|
||||
getFalsyFlags(declaredType) & TypeFlags.Undefined &&
|
||||
!(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined);
|
||||
getTypeFacts(declaredType) & TypeFacts.IsUndefined &&
|
||||
!(getTypeFacts(checkExpression(declaration.initializer)) & TypeFacts.IsUndefined);
|
||||
popTypeResolution();
|
||||
|
||||
return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType;
|
||||
@@ -25442,8 +25575,10 @@ namespace ts {
|
||||
!(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
|
||||
}
|
||||
|
||||
function isGenericTypeWithUnionConstraint(type: Type) {
|
||||
return !!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (TypeFlags.Nullable | TypeFlags.Union));
|
||||
function isGenericTypeWithUnionConstraint(type: Type): boolean {
|
||||
return type.flags & TypeFlags.Intersection ?
|
||||
some((type as IntersectionType).types, isGenericTypeWithUnionConstraint) :
|
||||
!!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (TypeFlags.Nullable | TypeFlags.Union));
|
||||
}
|
||||
|
||||
function isGenericTypeWithoutNullableConstraint(type: Type) {
|
||||
@@ -25474,7 +25609,7 @@ namespace ts {
|
||||
const substituteConstraints = !(checkMode && checkMode & CheckMode.Inferential) &&
|
||||
someType(type, isGenericTypeWithUnionConstraint) &&
|
||||
(isConstraintPosition(type, reference) || hasContextualTypeWithNoGenericTypes(reference, checkMode));
|
||||
return substituteConstraints ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type;
|
||||
return substituteConstraints ? mapType(type, getBaseConstraintOrType) : type;
|
||||
}
|
||||
|
||||
function isExportOrExportExpression(location: Node) {
|
||||
@@ -25774,7 +25909,7 @@ namespace ts {
|
||||
return convertAutoToAny(flowType);
|
||||
}
|
||||
}
|
||||
else if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
else if (!assumeInitialized && !(getTypeFacts(type) & TypeFacts.IsUndefined) && getTypeFacts(flowType) & TypeFacts.IsUndefined) {
|
||||
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
|
||||
// Return the declared type to reduce follow-on errors
|
||||
return type;
|
||||
@@ -28751,23 +28886,23 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isNullableType(type: Type) {
|
||||
return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable);
|
||||
return !!(getTypeFacts(type) & TypeFacts.IsUndefinedOrNull);
|
||||
}
|
||||
|
||||
function getNonNullableTypeIfNeeded(type: Type) {
|
||||
return isNullableType(type) ? getNonNullableType(type) : type;
|
||||
}
|
||||
|
||||
function reportObjectPossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
||||
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
||||
function reportObjectPossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) {
|
||||
error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ?
|
||||
Diagnostics.Object_is_possibly_null_or_undefined :
|
||||
Diagnostics.Object_is_possibly_undefined :
|
||||
Diagnostics.Object_is_possibly_null
|
||||
);
|
||||
}
|
||||
|
||||
function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
||||
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
||||
function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) {
|
||||
error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ?
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined :
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined :
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null
|
||||
@@ -28777,15 +28912,15 @@ namespace ts {
|
||||
function checkNonNullTypeWithReporter(
|
||||
type: Type,
|
||||
node: Node,
|
||||
reportError: (node: Node, kind: TypeFlags) => void
|
||||
reportError: (node: Node, facts: TypeFacts) => void
|
||||
): Type {
|
||||
if (strictNullChecks && type.flags & TypeFlags.Unknown) {
|
||||
error(node, Diagnostics.Object_is_of_type_unknown);
|
||||
return errorType;
|
||||
}
|
||||
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
|
||||
if (kind) {
|
||||
reportError(node, kind);
|
||||
const facts = getTypeFacts(type);
|
||||
if (facts & TypeFacts.IsUndefinedOrNull) {
|
||||
reportError(node, facts);
|
||||
const t = getNonNullableType(type);
|
||||
return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t;
|
||||
}
|
||||
@@ -29131,7 +29266,7 @@ namespace ts {
|
||||
assumeUninitialized = true;
|
||||
}
|
||||
const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
|
||||
if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
if (assumeUninitialized && !(getTypeFacts(propType) & TypeFacts.IsUndefined) && getTypeFacts(flowType) & TypeFacts.IsUndefined) {
|
||||
error(errorNode, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
|
||||
// Return the declared type to reduce follow-on errors
|
||||
return propType;
|
||||
@@ -33118,7 +33253,7 @@ namespace ts {
|
||||
const type = getTypeOfSymbol(symbol);
|
||||
if (strictNullChecks &&
|
||||
!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) &&
|
||||
!(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getFalsyFlags(type) & TypeFlags.Undefined)) {
|
||||
!(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type) & TypeFacts.IsUndefined)) {
|
||||
error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional);
|
||||
}
|
||||
}
|
||||
@@ -33555,7 +33690,7 @@ namespace ts {
|
||||
// In strict null checking mode, if a default value of a non-undefined type is specified, remove
|
||||
// undefined from the final type.
|
||||
if (strictNullChecks &&
|
||||
!(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & TypeFlags.Undefined)) {
|
||||
!(getTypeFacts(checkExpression(prop.objectAssignmentInitializer)) & TypeFacts.IsUndefined)) {
|
||||
sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined);
|
||||
}
|
||||
checkBinaryLikeExpression(prop.name, prop.equalsToken!, prop.objectAssignmentInitializer, checkMode);
|
||||
@@ -34014,7 +34149,7 @@ namespace ts {
|
||||
case SyntaxKind.BarBarToken:
|
||||
case SyntaxKind.BarBarEqualsToken: {
|
||||
const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ?
|
||||
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) :
|
||||
getUnionType([getNonNullableType(removeDefinitelyFalsyTypes(leftType)), rightType], UnionReduction.Subtype) :
|
||||
leftType;
|
||||
if (operator === SyntaxKind.BarBarEqualsToken) {
|
||||
checkAssignmentOperator(rightType);
|
||||
@@ -37793,7 +37928,7 @@ namespace ts {
|
||||
// For a binding pattern, validate the initializer and exit
|
||||
if (isBindingPattern(node.name)) {
|
||||
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
|
||||
const needCheckWidenedType = node.name.elements.length === 0;
|
||||
const needCheckWidenedType = !some(node.name.elements, not(isOmittedExpression));
|
||||
if (needCheckInitializer || needCheckWidenedType) {
|
||||
// Don't validate for-in initializer as it is already an error
|
||||
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
|
||||
@@ -37969,7 +38104,7 @@ namespace ts {
|
||||
if (isModuleExportsAccessExpression(location)) return;
|
||||
const type = checkTruthinessExpression(location);
|
||||
const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression);
|
||||
if (getFalsyFlags(type) || isPropertyExpressionCast) return;
|
||||
if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return;
|
||||
|
||||
// While it technically should be invalid for any known-truthy value
|
||||
// to be tested, we de-scope to functions and Promises unreferenced in
|
||||
@@ -39962,10 +40097,13 @@ namespace ts {
|
||||
const derivedPropertyFlags = derived.flags & SymbolFlags.PropertyOrAccessor;
|
||||
if (basePropertyFlags && derivedPropertyFlags) {
|
||||
// property/accessor is overridden with property/accessor
|
||||
if (baseDeclarationFlags & ModifierFlags.Abstract && !(base.valueDeclaration && isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer)
|
||||
|| base.valueDeclaration && base.valueDeclaration.parent.kind === SyntaxKind.InterfaceDeclaration
|
||||
if ((getCheckFlags(base) & CheckFlags.Synthetic
|
||||
? base.declarations?.some(d => isPropertyAbstractOrInterface(d, baseDeclarationFlags))
|
||||
: base.declarations?.every(d => isPropertyAbstractOrInterface(d, baseDeclarationFlags)))
|
||||
|| getCheckFlags(base) & CheckFlags.Mapped
|
||||
|| derived.valueDeclaration && isBinaryExpression(derived.valueDeclaration)) {
|
||||
// when the base property is abstract or from an interface, base/derived flags don't need to match
|
||||
// for intersection properties, this must be true of *any* of the declarations, for others it must be true of *all*
|
||||
// same when the derived property is from an assignment
|
||||
continue;
|
||||
}
|
||||
@@ -40023,7 +40161,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getNonInterhitedProperties(type: InterfaceType, baseTypes: BaseType[], properties: Symbol[]) {
|
||||
function isPropertyAbstractOrInterface(declaration: Declaration, baseDeclarationFlags: ModifierFlags) {
|
||||
return baseDeclarationFlags & ModifierFlags.Abstract && (!isPropertyDeclaration(declaration) || !declaration.initializer)
|
||||
|| isInterfaceDeclaration(declaration.parent);
|
||||
}
|
||||
|
||||
function getNonInheritedProperties(type: InterfaceType, baseTypes: BaseType[], properties: Symbol[]) {
|
||||
if (!length(baseTypes)) {
|
||||
return properties;
|
||||
}
|
||||
@@ -40097,7 +40240,7 @@ namespace ts {
|
||||
const propName = (member as PropertyDeclaration).name;
|
||||
if (isIdentifier(propName) || isPrivateIdentifier(propName) || isComputedPropertyName(propName)) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(member));
|
||||
if (!(type.flags & TypeFlags.AnyOrUnknown || getFalsyFlags(type) & TypeFlags.Undefined)) {
|
||||
if (!(type.flags & TypeFlags.AnyOrUnknown || getTypeFacts(type) & TypeFacts.IsUndefined)) {
|
||||
if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
|
||||
error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName));
|
||||
}
|
||||
@@ -40123,7 +40266,7 @@ namespace ts {
|
||||
setParent(reference, staticBlock);
|
||||
reference.flowNode = staticBlock.returnFlowNode;
|
||||
const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
|
||||
if (!(getFalsyFlags(flowType) & TypeFlags.Undefined)) {
|
||||
if (!(getTypeFacts(flowType) & TypeFacts.IsUndefined)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -40139,7 +40282,7 @@ namespace ts {
|
||||
setParent(reference, constructor);
|
||||
reference.flowNode = constructor.returnFlowNode;
|
||||
const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
|
||||
return !(getFalsyFlags(flowType) & TypeFlags.Undefined);
|
||||
return !(getTypeFacts(flowType) & TypeFacts.IsUndefined);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2035,7 +2035,7 @@ namespace ts {
|
||||
return comparer(a, b);
|
||||
}
|
||||
|
||||
export function compareProperties<T, K extends keyof T>(a: T | undefined, b: T | undefined, key: K, comparer: Comparer<T[K]>): Comparison {
|
||||
export function compareProperties<T extends object, K extends keyof T>(a: T | undefined, b: T | undefined, key: K, comparer: Comparer<T[K]>): Comparison {
|
||||
return a === b ? Comparison.EqualTo :
|
||||
a === undefined ? Comparison.LessThan :
|
||||
b === undefined ? Comparison.GreaterThan :
|
||||
|
||||
@@ -1526,6 +1526,10 @@
|
||||
"category": "Error",
|
||||
"code": 2207
|
||||
},
|
||||
"This type parameter probably needs an `extends object` constraint.": {
|
||||
"category": "Error",
|
||||
"code": 2208
|
||||
},
|
||||
|
||||
"The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": {
|
||||
"category": "Error",
|
||||
@@ -3471,6 +3475,10 @@
|
||||
"category": "Error",
|
||||
"code": 2839
|
||||
},
|
||||
"An interface cannot extend a primitive type like '{0}'; an interface can only extend named types and classes": {
|
||||
"category": "Error",
|
||||
"code": 2840
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -2413,8 +2413,8 @@ namespace ts {
|
||||
);
|
||||
if (
|
||||
!pathAndExtension && packageInfo
|
||||
&& packageInfo.packageJsonContent.exports === undefined
|
||||
&& packageInfo.packageJsonContent.main === undefined
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
&& (packageInfo.packageJsonContent.exports === undefined || packageInfo.packageJsonContent.exports === null)
|
||||
&& state.features & NodeResolutionFeatures.EsmMode
|
||||
) {
|
||||
// EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume
|
||||
|
||||
@@ -5398,6 +5398,11 @@ namespace ts {
|
||||
// Flags that require TypeFlags.Union
|
||||
/* @internal */
|
||||
ContainsIntersections = 1 << 24, // Union contains intersections
|
||||
/* @internal */
|
||||
IsUnknownLikeUnionComputed = 1 << 25, // IsUnknownLikeUnion flag has been computed
|
||||
/* @internal */
|
||||
IsUnknownLikeUnion = 1 << 26, // Union of null, undefined, and empty object type
|
||||
/* @internal */
|
||||
|
||||
// Flags that require TypeFlags.Intersection
|
||||
/* @internal */
|
||||
@@ -5878,7 +5883,7 @@ namespace ts {
|
||||
AlwaysStrict = 1 << 10, // Always use strict rules for contravariant inferences
|
||||
MaxValue = 1 << 11, // Seed for inference priority tracking
|
||||
|
||||
PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
|
||||
PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
|
||||
Circularity = -1, // Inference circularity (value less than all other priorities)
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1564,7 +1564,7 @@ type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
|
||||
/**
|
||||
* Exclude null and undefined from T
|
||||
*/
|
||||
type NonNullable<T> = T extends null | undefined ? never : T;
|
||||
type NonNullable<T> = T & {};
|
||||
|
||||
/**
|
||||
* Obtain the parameters of a function type in a tuple
|
||||
|
||||
@@ -13803,6 +13803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[此类型参数可能需要 "extends object" 约束。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13803,6 +13803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[此類型參數可能需要 'extends object' 限制式。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13812,6 +13812,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Tento parametr typu pravděpodobně potřebuje omezení „extends object“.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13797,6 +13797,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dieser Typparameter benötigt wahrscheinlich eine „extends object“-Einschränkung.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13815,6 +13815,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Puede que este parámetro de tipo necesite una restricción “extends object”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13815,6 +13815,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ce paramètre de type nécessite probablement une contrainte 'extends object'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13803,6 +13803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Questo parametro di tipo richiede probabilmente un vincolo 'extends object'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13803,6 +13803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[この型パラメーターには、`extends object` 制約が必要な可能性があります。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13803,6 +13803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[이 형식 매개 변수에는 `extends object` 제약 조건이 필요할 수 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13790,6 +13790,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ten parametr typu prawdopodobnie wymaga ograniczenia „extends object”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13793,6 +13793,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Esse parâmetro de tipo provavelmente precisa de uma restrição `extends object.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13802,6 +13802,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Возможно, для этого параметра типа требуется ограничение "extends object".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -13796,6 +13796,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_type_parameter_probably_needs_an_extends_object_constraint_2208" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This type parameter probably needs an `extends object` constraint.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Bu tür parametresi için bir `nesneyi genişletir` kısıtlaması gerekiyor olabilir.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
|
||||
@@ -617,7 +617,6 @@ namespace ts.formatting {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -835,7 +834,7 @@ namespace ts.formatting {
|
||||
const listEndToken = getCloseTokenForOpenToken(listStartToken);
|
||||
if (listEndToken !== SyntaxKind.Unknown && formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) {
|
||||
let tokenInfo: TokenInfo | undefined = formattingScanner.readTokenInfo(parent);
|
||||
if (tokenInfo.token.kind === SyntaxKind.CommaToken && isCallLikeExpression(parent)) {
|
||||
if (tokenInfo.token.kind === SyntaxKind.CommaToken) {
|
||||
// consume the comma
|
||||
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
|
||||
tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined;
|
||||
@@ -1311,6 +1310,12 @@ namespace ts.formatting {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
if ((node as FunctionDeclaration).typeParameters === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
@@ -1327,7 +1332,19 @@ namespace ts.formatting {
|
||||
return SyntaxKind.OpenParenToken;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
if ((node as ClassDeclaration).typeParameters === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.TypeReference:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
case SyntaxKind.ImportType:
|
||||
if ((node as TypeReferenceNode).typeArguments === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ts.InlayHints {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTypeNode(node)) {
|
||||
if (isTypeNode(node) && !isExpressionWithTypeArguments(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.main = void 0;
|
||||
function main() {
|
||||
for (var _i = 0, doesNotExist_1 = doesNotExist; _i < doesNotExist_1.length; _i++) {
|
||||
var _a = doesNotExist_1[_i];
|
||||
}
|
||||
}
|
||||
exports.main = main;
|
||||
@@ -0,0 +1,50 @@
|
||||
//// [accessorsOverrideProperty8.ts]
|
||||
type Types = 'boolean' | 'unknown' | 'string';
|
||||
|
||||
type Properties<T extends { [key: string]: Types }> = {
|
||||
readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown
|
||||
}
|
||||
|
||||
type AnyCtor<P extends object> = new (...a: any[]) => P
|
||||
|
||||
declare function classWithProperties<T extends { [key: string]: Types }, P extends object>(properties: T, klass: AnyCtor<P>): {
|
||||
new(): P & Properties<T>;
|
||||
prototype: P & Properties<T>
|
||||
};
|
||||
|
||||
const Base = classWithProperties({
|
||||
get x() { return 'boolean' as const },
|
||||
y: 'string',
|
||||
}, class Base {
|
||||
});
|
||||
|
||||
class MyClass extends Base {
|
||||
get x() {
|
||||
return false;
|
||||
}
|
||||
get y() {
|
||||
return 'hi'
|
||||
}
|
||||
}
|
||||
|
||||
const mine = new MyClass();
|
||||
const value = mine.x;
|
||||
|
||||
|
||||
|
||||
//// [accessorsOverrideProperty8.js]
|
||||
const Base = classWithProperties({
|
||||
get x() { return 'boolean'; },
|
||||
y: 'string',
|
||||
}, class Base {
|
||||
});
|
||||
class MyClass extends Base {
|
||||
get x() {
|
||||
return false;
|
||||
}
|
||||
get y() {
|
||||
return 'hi';
|
||||
}
|
||||
}
|
||||
const mine = new MyClass();
|
||||
const value = mine.x;
|
||||
@@ -0,0 +1,93 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts ===
|
||||
type Types = 'boolean' | 'unknown' | 'string';
|
||||
>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0))
|
||||
|
||||
type Properties<T extends { [key: string]: Types }> = {
|
||||
>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16))
|
||||
>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 2, 29))
|
||||
>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0))
|
||||
|
||||
readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown
|
||||
>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16))
|
||||
>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 2, 16))
|
||||
>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 3, 14))
|
||||
}
|
||||
|
||||
type AnyCtor<P extends object> = new (...a: any[]) => P
|
||||
>AnyCtor : Symbol(AnyCtor, Decl(accessorsOverrideProperty8.ts, 4, 1))
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 6, 13))
|
||||
>a : Symbol(a, Decl(accessorsOverrideProperty8.ts, 6, 38))
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 6, 13))
|
||||
|
||||
declare function classWithProperties<T extends { [key: string]: Types }, P extends object>(properties: T, klass: AnyCtor<P>): {
|
||||
>classWithProperties : Symbol(classWithProperties, Decl(accessorsOverrideProperty8.ts, 6, 55))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37))
|
||||
>key : Symbol(key, Decl(accessorsOverrideProperty8.ts, 8, 50))
|
||||
>Types : Symbol(Types, Decl(accessorsOverrideProperty8.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72))
|
||||
>properties : Symbol(properties, Decl(accessorsOverrideProperty8.ts, 8, 91))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37))
|
||||
>klass : Symbol(klass, Decl(accessorsOverrideProperty8.ts, 8, 105))
|
||||
>AnyCtor : Symbol(AnyCtor, Decl(accessorsOverrideProperty8.ts, 4, 1))
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72))
|
||||
|
||||
new(): P & Properties<T>;
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72))
|
||||
>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37))
|
||||
|
||||
prototype: P & Properties<T>
|
||||
>prototype : Symbol(prototype, Decl(accessorsOverrideProperty8.ts, 9, 29))
|
||||
>P : Symbol(P, Decl(accessorsOverrideProperty8.ts, 8, 72))
|
||||
>Properties : Symbol(Properties, Decl(accessorsOverrideProperty8.ts, 0, 46))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty8.ts, 8, 37))
|
||||
|
||||
};
|
||||
|
||||
const Base = classWithProperties({
|
||||
>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 13, 5))
|
||||
>classWithProperties : Symbol(classWithProperties, Decl(accessorsOverrideProperty8.ts, 6, 55))
|
||||
|
||||
get x() { return 'boolean' as const },
|
||||
>x : Symbol(x, Decl(accessorsOverrideProperty8.ts, 13, 34))
|
||||
>const : Symbol(const)
|
||||
|
||||
y: 'string',
|
||||
>y : Symbol(y, Decl(accessorsOverrideProperty8.ts, 14, 42))
|
||||
|
||||
}, class Base {
|
||||
>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 16, 2))
|
||||
|
||||
});
|
||||
|
||||
class MyClass extends Base {
|
||||
>MyClass : Symbol(MyClass, Decl(accessorsOverrideProperty8.ts, 17, 3))
|
||||
>Base : Symbol(Base, Decl(accessorsOverrideProperty8.ts, 13, 5))
|
||||
|
||||
get x() {
|
||||
>x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28))
|
||||
|
||||
return false;
|
||||
}
|
||||
get y() {
|
||||
>y : Symbol(MyClass.y, Decl(accessorsOverrideProperty8.ts, 22, 5))
|
||||
|
||||
return 'hi'
|
||||
}
|
||||
}
|
||||
|
||||
const mine = new MyClass();
|
||||
>mine : Symbol(mine, Decl(accessorsOverrideProperty8.ts, 28, 5))
|
||||
>MyClass : Symbol(MyClass, Decl(accessorsOverrideProperty8.ts, 17, 3))
|
||||
|
||||
const value = mine.x;
|
||||
>value : Symbol(value, Decl(accessorsOverrideProperty8.ts, 29, 5))
|
||||
>mine.x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28))
|
||||
>mine : Symbol(mine, Decl(accessorsOverrideProperty8.ts, 28, 5))
|
||||
>x : Symbol(MyClass.x, Decl(accessorsOverrideProperty8.ts, 19, 28))
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty8.ts ===
|
||||
type Types = 'boolean' | 'unknown' | 'string';
|
||||
>Types : "string" | "boolean" | "unknown"
|
||||
|
||||
type Properties<T extends { [key: string]: Types }> = {
|
||||
>Properties : Properties<T>
|
||||
>key : string
|
||||
|
||||
readonly [key in keyof T]: T[key] extends 'boolean' ? boolean : T[key] extends 'string' ? string : unknown
|
||||
}
|
||||
|
||||
type AnyCtor<P extends object> = new (...a: any[]) => P
|
||||
>AnyCtor : AnyCtor<P>
|
||||
>a : any[]
|
||||
|
||||
declare function classWithProperties<T extends { [key: string]: Types }, P extends object>(properties: T, klass: AnyCtor<P>): {
|
||||
>classWithProperties : <T extends { [key: string]: Types; }, P extends object>(properties: T, klass: AnyCtor<P>) => { new (): P & Properties<T>; prototype: P & Properties<T>;}
|
||||
>key : string
|
||||
>properties : T
|
||||
>klass : AnyCtor<P>
|
||||
|
||||
new(): P & Properties<T>;
|
||||
prototype: P & Properties<T>
|
||||
>prototype : P & Properties<T>
|
||||
|
||||
};
|
||||
|
||||
const Base = classWithProperties({
|
||||
>Base : { new (): Base & Properties<{ readonly x: "boolean"; y: "string"; }>; prototype: Base & Properties<{ readonly x: "boolean"; y: "string"; }>; }
|
||||
>classWithProperties({ get x() { return 'boolean' as const }, y: 'string',}, class Base {}) : { new (): Base & Properties<{ readonly x: "boolean"; y: "string"; }>; prototype: Base & Properties<{ readonly x: "boolean"; y: "string"; }>; }
|
||||
>classWithProperties : <T extends { [key: string]: Types; }, P extends object>(properties: T, klass: AnyCtor<P>) => { new (): P & Properties<T>; prototype: P & Properties<T>; }
|
||||
>{ get x() { return 'boolean' as const }, y: 'string',} : { readonly x: "boolean"; y: "string"; }
|
||||
|
||||
get x() { return 'boolean' as const },
|
||||
>x : "boolean"
|
||||
>'boolean' as const : "boolean"
|
||||
>'boolean' : "boolean"
|
||||
|
||||
y: 'string',
|
||||
>y : "string"
|
||||
>'string' : "string"
|
||||
|
||||
}, class Base {
|
||||
>class Base {} : typeof Base
|
||||
>Base : typeof Base
|
||||
|
||||
});
|
||||
|
||||
class MyClass extends Base {
|
||||
>MyClass : MyClass
|
||||
>Base : Base & Properties<{ readonly x: "boolean"; y: "string"; }>
|
||||
|
||||
get x() {
|
||||
>x : boolean
|
||||
|
||||
return false;
|
||||
>false : false
|
||||
}
|
||||
get y() {
|
||||
>y : string
|
||||
|
||||
return 'hi'
|
||||
>'hi' : "hi"
|
||||
}
|
||||
}
|
||||
|
||||
const mine = new MyClass();
|
||||
>mine : MyClass
|
||||
>new MyClass() : MyClass
|
||||
>MyClass : typeof MyClass
|
||||
|
||||
const value = mine.x;
|
||||
>value : boolean
|
||||
>mine.x : boolean
|
||||
>mine : MyClass
|
||||
>x : boolean
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//// [accessorsOverrideProperty9.ts]
|
||||
// #41347, based on microsoft/rushstack
|
||||
|
||||
// Mixin utilities
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
export type PropertiesOf<T> = { [K in keyof T]: T[K] };
|
||||
|
||||
interface IApiItemConstructor extends Constructor<ApiItem>, PropertiesOf<typeof ApiItem> {}
|
||||
|
||||
// Base class
|
||||
class ApiItem {
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Normal subclass
|
||||
class ApiEnumMember extends ApiItem {
|
||||
}
|
||||
|
||||
// Mixin base class
|
||||
interface ApiItemContainerMixin extends ApiItem {
|
||||
readonly members: ReadonlyArray<ApiItem>;
|
||||
}
|
||||
|
||||
function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
||||
baseClass: TBaseClass
|
||||
): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) {
|
||||
abstract class MixedClass extends baseClass implements ApiItemContainerMixin {
|
||||
public constructor(...args: any[]) {
|
||||
super(...args);
|
||||
}
|
||||
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
return MixedClass;
|
||||
}
|
||||
|
||||
// Subclass inheriting from mixin
|
||||
export class ApiEnum extends ApiItemContainerMixin(ApiItem) {
|
||||
// This worked prior to TypeScript 4.0:
|
||||
public get members(): ReadonlyArray<ApiEnumMember> {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [accessorsOverrideProperty9.js]
|
||||
// #41347, based on microsoft/rushstack
|
||||
// Base class
|
||||
class ApiItem {
|
||||
get members() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
// Normal subclass
|
||||
class ApiEnumMember extends ApiItem {
|
||||
}
|
||||
function ApiItemContainerMixin(baseClass) {
|
||||
class MixedClass extends baseClass {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
}
|
||||
get members() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return MixedClass;
|
||||
}
|
||||
// Subclass inheriting from mixin
|
||||
export class ApiEnum extends ApiItemContainerMixin(ApiItem) {
|
||||
// This worked prior to TypeScript 4.0:
|
||||
get members() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts ===
|
||||
// #41347, based on microsoft/rushstack
|
||||
|
||||
// Mixin utilities
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
>Constructor : Symbol(Constructor, Decl(accessorsOverrideProperty9.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 3, 24))
|
||||
>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 3, 39))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 3, 24))
|
||||
|
||||
export type PropertiesOf<T> = { [K in keyof T]: T[K] };
|
||||
>PropertiesOf : Symbol(PropertiesOf, Decl(accessorsOverrideProperty9.ts, 3, 60))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25))
|
||||
>K : Symbol(K, Decl(accessorsOverrideProperty9.ts, 4, 33))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25))
|
||||
>T : Symbol(T, Decl(accessorsOverrideProperty9.ts, 4, 25))
|
||||
>K : Symbol(K, Decl(accessorsOverrideProperty9.ts, 4, 33))
|
||||
|
||||
interface IApiItemConstructor extends Constructor<ApiItem>, PropertiesOf<typeof ApiItem> {}
|
||||
>IApiItemConstructor : Symbol(IApiItemConstructor, Decl(accessorsOverrideProperty9.ts, 4, 55))
|
||||
>Constructor : Symbol(Constructor, Decl(accessorsOverrideProperty9.ts, 0, 0))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
>PropertiesOf : Symbol(PropertiesOf, Decl(accessorsOverrideProperty9.ts, 3, 60))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
// Base class
|
||||
class ApiItem {
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
>members : Symbol(ApiItem.members, Decl(accessorsOverrideProperty9.ts, 9, 15))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Normal subclass
|
||||
class ApiEnumMember extends ApiItem {
|
||||
>ApiEnumMember : Symbol(ApiEnumMember, Decl(accessorsOverrideProperty9.ts, 13, 1))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
}
|
||||
|
||||
// Mixin base class
|
||||
interface ApiItemContainerMixin extends ApiItem {
|
||||
>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
readonly members: ReadonlyArray<ApiItem>;
|
||||
>members : Symbol(ApiItemContainerMixin.members, Decl(accessorsOverrideProperty9.ts, 20, 49))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
}
|
||||
|
||||
function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
||||
>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1))
|
||||
>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31))
|
||||
>IApiItemConstructor : Symbol(IApiItemConstructor, Decl(accessorsOverrideProperty9.ts, 4, 55))
|
||||
|
||||
baseClass: TBaseClass
|
||||
>baseClass : Symbol(baseClass, Decl(accessorsOverrideProperty9.ts, 24, 71))
|
||||
>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31))
|
||||
|
||||
): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) {
|
||||
>TBaseClass : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31))
|
||||
>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 26, 22))
|
||||
>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1))
|
||||
|
||||
abstract class MixedClass extends baseClass implements ApiItemContainerMixin {
|
||||
>MixedClass : Symbol(MixedClass, Decl(accessorsOverrideProperty9.ts, 26, 65))
|
||||
>baseClass : Symbol(baseClass, Decl(accessorsOverrideProperty9.ts, 24, 71))
|
||||
>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1))
|
||||
|
||||
public constructor(...args: any[]) {
|
||||
>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 28, 23))
|
||||
|
||||
super(...args);
|
||||
>super : Symbol(TBaseClass, Decl(accessorsOverrideProperty9.ts, 24, 31))
|
||||
>args : Symbol(args, Decl(accessorsOverrideProperty9.ts, 28, 23))
|
||||
}
|
||||
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
>members : Symbol(MixedClass.members, Decl(accessorsOverrideProperty9.ts, 30, 5))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
return MixedClass;
|
||||
>MixedClass : Symbol(MixedClass, Decl(accessorsOverrideProperty9.ts, 26, 65))
|
||||
}
|
||||
|
||||
// Subclass inheriting from mixin
|
||||
export class ApiEnum extends ApiItemContainerMixin(ApiItem) {
|
||||
>ApiEnum : Symbol(ApiEnum, Decl(accessorsOverrideProperty9.ts, 38, 1))
|
||||
>ApiItemContainerMixin : Symbol(ApiItemContainerMixin, Decl(accessorsOverrideProperty9.ts, 22, 1), Decl(accessorsOverrideProperty9.ts, 17, 1))
|
||||
>ApiItem : Symbol(ApiItem, Decl(accessorsOverrideProperty9.ts, 6, 91))
|
||||
|
||||
// This worked prior to TypeScript 4.0:
|
||||
public get members(): ReadonlyArray<ApiEnumMember> {
|
||||
>members : Symbol(ApiEnum.members, Decl(accessorsOverrideProperty9.ts, 41, 61))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --))
|
||||
>ApiEnumMember : Symbol(ApiEnumMember, Decl(accessorsOverrideProperty9.ts, 13, 1))
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
=== tests/cases/conformance/classes/propertyMemberDeclarations/accessorsOverrideProperty9.ts ===
|
||||
// #41347, based on microsoft/rushstack
|
||||
|
||||
// Mixin utilities
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
>Constructor : Constructor<T>
|
||||
>args : any[]
|
||||
|
||||
export type PropertiesOf<T> = { [K in keyof T]: T[K] };
|
||||
>PropertiesOf : PropertiesOf<T>
|
||||
|
||||
interface IApiItemConstructor extends Constructor<ApiItem>, PropertiesOf<typeof ApiItem> {}
|
||||
>ApiItem : typeof ApiItem
|
||||
|
||||
// Base class
|
||||
class ApiItem {
|
||||
>ApiItem : ApiItem
|
||||
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
>members : readonly ApiItem[]
|
||||
|
||||
return [];
|
||||
>[] : never[]
|
||||
}
|
||||
}
|
||||
|
||||
// Normal subclass
|
||||
class ApiEnumMember extends ApiItem {
|
||||
>ApiEnumMember : ApiEnumMember
|
||||
>ApiItem : ApiItem
|
||||
}
|
||||
|
||||
// Mixin base class
|
||||
interface ApiItemContainerMixin extends ApiItem {
|
||||
readonly members: ReadonlyArray<ApiItem>;
|
||||
>members : readonly ApiItem[]
|
||||
}
|
||||
|
||||
function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(
|
||||
>ApiItemContainerMixin : <TBaseClass extends IApiItemConstructor>(baseClass: TBaseClass) => TBaseClass & (new (...args: any[]) => ApiItemContainerMixin)
|
||||
|
||||
baseClass: TBaseClass
|
||||
>baseClass : TBaseClass
|
||||
|
||||
): TBaseClass & (new (...args: any[]) => ApiItemContainerMixin) {
|
||||
>args : any[]
|
||||
|
||||
abstract class MixedClass extends baseClass implements ApiItemContainerMixin {
|
||||
>MixedClass : MixedClass
|
||||
>baseClass : ApiItem
|
||||
|
||||
public constructor(...args: any[]) {
|
||||
>args : any[]
|
||||
|
||||
super(...args);
|
||||
>super(...args) : void
|
||||
>super : TBaseClass
|
||||
>...args : any
|
||||
>args : any[]
|
||||
}
|
||||
|
||||
public get members(): ReadonlyArray<ApiItem> {
|
||||
>members : readonly ApiItem[]
|
||||
|
||||
return [];
|
||||
>[] : never[]
|
||||
}
|
||||
}
|
||||
|
||||
return MixedClass;
|
||||
>MixedClass : ((abstract new (...args: any[]) => MixedClass) & { prototype: ApiItemContainerMixin<any>.MixedClass; }) & TBaseClass
|
||||
}
|
||||
|
||||
// Subclass inheriting from mixin
|
||||
export class ApiEnum extends ApiItemContainerMixin(ApiItem) {
|
||||
>ApiEnum : ApiEnum
|
||||
>ApiItemContainerMixin(ApiItem) : ApiItem & ApiItemContainerMixin
|
||||
>ApiItemContainerMixin : <TBaseClass extends IApiItemConstructor>(baseClass: TBaseClass) => TBaseClass & (new (...args: any[]) => ApiItemContainerMixin)
|
||||
>ApiItem : typeof ApiItem
|
||||
|
||||
// This worked prior to TypeScript 4.0:
|
||||
public get members(): ReadonlyArray<ApiEnumMember> {
|
||||
>members : readonly ApiEnumMember[]
|
||||
|
||||
return [];
|
||||
>[] : never[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ function f01(x: unknown) {
|
||||
>undefined : undefined
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {} | null
|
||||
>"string" : "string"
|
||||
|
||||
x; // string | undefined
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(12,5): error TS2322: Type 'T' is not assignable to type 'NonNullable<T>'.
|
||||
Type 'T' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(17,5): error TS2322: Type 'T' is not assignable to type 'NonNullable<T>'.
|
||||
Type 'string | undefined' is not assignable to type 'NonNullable<T>'.
|
||||
Type 'undefined' is not assignable to type 'NonNullable<T>'.
|
||||
Type 'undefined' is not assignable to type 'T'.
|
||||
'undefined' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | undefined'.
|
||||
Type 'T' is not assignable to type '{}'.
|
||||
Type 'string | undefined' is not assignable to type '{}'.
|
||||
Type 'undefined' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(24,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
|
||||
Type 'undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T] & {}'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(29,5): error TS2322: Type 'T["x"]' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
Type 'string | undefined' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
Type 'undefined' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
Type 'undefined' is not assignable to type '{}'.
|
||||
Type 'T["x"]' is not assignable to type '{}'.
|
||||
Type 'string | undefined' is not assignable to type '{}'.
|
||||
Type 'undefined' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2322: Type 'FunctionProperties<T>' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'FunctionProperties<T>'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2322: Type 'NonFunctionProperties<T>' is not assignable to type 'T'.
|
||||
@@ -72,6 +83,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
y = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'NonNullable<T>'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{}'.
|
||||
!!! related TS2208 tests/cases/conformance/types/conditional/conditionalTypes1.ts:10:13: This type parameter probably needs an `extends object` constraint.
|
||||
}
|
||||
|
||||
function f2<T extends string | undefined>(x: T, y: NonNullable<T>) {
|
||||
@@ -81,6 +94,11 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'NonNullable<T>'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'NonNullable<T>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable<T>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'undefined' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | undefined'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type '{}'.
|
||||
let s1: string = x; // Error
|
||||
let s2: string = y;
|
||||
}
|
||||
@@ -90,7 +108,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
y = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable<Partial<T>[keyof T]>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T] & {}'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
}
|
||||
|
||||
function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"]>) {
|
||||
@@ -100,6 +119,10 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
!!! error TS2322: Type 'T["x"]' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable<T["x"]>'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T["x"]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type '{}'.
|
||||
let s1: string = x; // Error
|
||||
let s2: string = y;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ function f2<T extends string | undefined>(x: T, y: NonNullable<T>) {
|
||||
|
||||
let s2: string = y;
|
||||
>s2 : string
|
||||
>y : NonNullable<T>
|
||||
>y : string
|
||||
}
|
||||
|
||||
function f3<T>(x: Partial<T>[keyof T], y: NonNullable<Partial<T>[keyof T]>) {
|
||||
@@ -96,7 +96,7 @@ function f4<T extends { x: string | undefined }>(x: T["x"], y: NonNullable<T["x"
|
||||
|
||||
let s2: string = y;
|
||||
>s2 : string
|
||||
>y : NonNullable<T["x"]>
|
||||
>y : string
|
||||
}
|
||||
|
||||
type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean };
|
||||
|
||||
@@ -32,7 +32,7 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(74,12): error TS2
|
||||
Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (7 errors) ====
|
||||
@@ -155,8 +155,7 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
~
|
||||
!!! error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
!!! error TS2345: Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
|
||||
!!! error TS2345: Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
}
|
||||
|
||||
// Repros from #22860
|
||||
|
||||
@@ -10,7 +10,7 @@ function f1<T extends string | undefined>(x: T, y: { a: T }, z: [T]): string {
|
||||
>x : T
|
||||
|
||||
x;
|
||||
>x : T
|
||||
>x : NonNullable<T>
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
@@ -67,7 +67,7 @@ function f2<T>(x: Extract<T, string | undefined> | null): string {
|
||||
>x : Extract<T, string | undefined> | null
|
||||
|
||||
x;
|
||||
>x : Extract<T, string | undefined>
|
||||
>x : NonNullable<Extract<T, string | undefined>>
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
@@ -404,11 +404,11 @@ function fx1<T, K extends keyof T>(obj: T, key: K) {
|
||||
>key : K
|
||||
|
||||
const x2 = obj && obj[key];
|
||||
>x2 : T[K]
|
||||
>obj && obj[key] : T[K]
|
||||
>obj : T
|
||||
>obj[key] : T[K]
|
||||
>x2 : NonNullable<T>[K]
|
||||
>obj && obj[key] : NonNullable<T>[K]
|
||||
>obj : T
|
||||
>obj[key] : NonNullable<T>[K]
|
||||
>obj : NonNullable<T>
|
||||
>key : K
|
||||
}
|
||||
|
||||
@@ -438,8 +438,8 @@ function fx3<T extends Record<keyof T, string> | undefined, K extends keyof T>(o
|
||||
>key : K
|
||||
|
||||
const x1 = obj[key]; // Error
|
||||
>x1 : NonNullable<Record<keyof T, string>>[K]
|
||||
>obj[key] : NonNullable<Record<keyof T, string>>[K]
|
||||
>x1 : Record<keyof T, string>[K]
|
||||
>obj[key] : Record<keyof T, string>[K]
|
||||
>obj : Record<keyof T, string> | undefined
|
||||
>key : K
|
||||
|
||||
@@ -469,14 +469,14 @@ class TableBaseEnum<
|
||||
>null : null
|
||||
|
||||
iSpec[null! as keyof InternalSpec]; // Error, object possibly undefined
|
||||
>iSpec[null! as keyof InternalSpec] : NonNullable<Record<keyof PublicSpec, any>>[keyof InternalSpec]
|
||||
>iSpec[null! as keyof InternalSpec] : Record<keyof PublicSpec, any>[keyof InternalSpec]
|
||||
>iSpec : Record<keyof PublicSpec, any> | undefined
|
||||
>null! as keyof InternalSpec : keyof InternalSpec
|
||||
>null! : never
|
||||
>null : null
|
||||
|
||||
iSpec[null! as keyof PublicSpec]; // Error, object possibly undefined
|
||||
>iSpec[null! as keyof PublicSpec] : NonNullable<Record<keyof PublicSpec, any>>[keyof PublicSpec]
|
||||
>iSpec[null! as keyof PublicSpec] : Record<keyof PublicSpec, any>[keyof PublicSpec]
|
||||
>iSpec : Record<keyof PublicSpec, any> | undefined
|
||||
>null! as keyof PublicSpec : keyof PublicSpec
|
||||
>null! : never
|
||||
|
||||
@@ -181,7 +181,7 @@ function f8<T>(x: T) {
|
||||
>x : T
|
||||
|
||||
x; // {}
|
||||
>x : T
|
||||
>x : NonNullable<T>
|
||||
}
|
||||
else {
|
||||
x; // {}
|
||||
|
||||
@@ -16,7 +16,7 @@ function f1(x: unknown) {
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
@@ -40,7 +40,7 @@ function f2(x: unknown) {
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {} | undefined
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
@@ -64,7 +64,7 @@ function f3(x: unknown) {
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
@@ -88,7 +88,7 @@ function f4(x: unknown) {
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
@@ -126,7 +126,7 @@ function f5(x: unknown) {
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {} | undefined
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
@@ -150,12 +150,12 @@ function f6(x: unknown) {
|
||||
}
|
||||
else {
|
||||
x;
|
||||
>x : unknown
|
||||
>x : {} | undefined
|
||||
|
||||
if (typeof x === 'object') {
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {} | undefined
|
||||
>'object' : "object"
|
||||
|
||||
obj(x);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
tests/cases/compiler/b.ts(2,14): error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized.
|
||||
tests/cases/compiler/c.ts(3,14): error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized.
|
||||
|
||||
|
||||
==== tests/cases/compiler/a.d.ts (0 errors) ====
|
||||
export declare const timestampSymbol: unique symbol;
|
||||
|
||||
export declare const Timestamp: {
|
||||
[TKey in typeof timestampSymbol]: true;
|
||||
};
|
||||
|
||||
export declare function now(): typeof Timestamp;
|
||||
|
||||
==== tests/cases/compiler/b.ts (1 errors) ====
|
||||
import * as x from "./a";
|
||||
export const timestamp = x.now();
|
||||
~~~~~~~~~
|
||||
!!! error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized.
|
||||
|
||||
==== tests/cases/compiler/c.ts (1 errors) ====
|
||||
import { now } from "./a";
|
||||
|
||||
export const timestamp = now();
|
||||
~~~~~~~~~
|
||||
!!! error TS4118: The type of this node cannot be serialized because its property '[timestampSymbol]' cannot be serialized.
|
||||
@@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/declarationEmitMappedTypeTemplateTypeofSymbol.ts] ////
|
||||
|
||||
//// [a.d.ts]
|
||||
export declare const timestampSymbol: unique symbol;
|
||||
|
||||
export declare const Timestamp: {
|
||||
[TKey in typeof timestampSymbol]: true;
|
||||
};
|
||||
|
||||
export declare function now(): typeof Timestamp;
|
||||
|
||||
//// [b.ts]
|
||||
import * as x from "./a";
|
||||
export const timestamp = x.now();
|
||||
|
||||
//// [c.ts]
|
||||
import { now } from "./a";
|
||||
|
||||
export const timestamp = now();
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.timestamp = void 0;
|
||||
var x = require("./a");
|
||||
exports.timestamp = x.now();
|
||||
//// [c.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.timestamp = void 0;
|
||||
var a_1 = require("./a");
|
||||
exports.timestamp = (0, a_1.now)();
|
||||
@@ -0,0 +1,35 @@
|
||||
=== tests/cases/compiler/a.d.ts ===
|
||||
export declare const timestampSymbol: unique symbol;
|
||||
>timestampSymbol : Symbol(timestampSymbol, Decl(a.d.ts, 0, 20))
|
||||
|
||||
export declare const Timestamp: {
|
||||
>Timestamp : Symbol(Timestamp, Decl(a.d.ts, 2, 20))
|
||||
|
||||
[TKey in typeof timestampSymbol]: true;
|
||||
>TKey : Symbol(TKey, Decl(a.d.ts, 3, 5))
|
||||
>timestampSymbol : Symbol(timestampSymbol, Decl(a.d.ts, 0, 20))
|
||||
|
||||
};
|
||||
|
||||
export declare function now(): typeof Timestamp;
|
||||
>now : Symbol(now, Decl(a.d.ts, 4, 2))
|
||||
>Timestamp : Symbol(Timestamp, Decl(a.d.ts, 2, 20))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import * as x from "./a";
|
||||
>x : Symbol(x, Decl(b.ts, 0, 6))
|
||||
|
||||
export const timestamp = x.now();
|
||||
>timestamp : Symbol(timestamp, Decl(b.ts, 1, 12))
|
||||
>x.now : Symbol(x.now, Decl(a.d.ts, 4, 2))
|
||||
>x : Symbol(x, Decl(b.ts, 0, 6))
|
||||
>now : Symbol(x.now, Decl(a.d.ts, 4, 2))
|
||||
|
||||
=== tests/cases/compiler/c.ts ===
|
||||
import { now } from "./a";
|
||||
>now : Symbol(now, Decl(c.ts, 0, 8))
|
||||
|
||||
export const timestamp = now();
|
||||
>timestamp : Symbol(timestamp, Decl(c.ts, 2, 12))
|
||||
>now : Symbol(now, Decl(c.ts, 0, 8))
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
=== tests/cases/compiler/a.d.ts ===
|
||||
export declare const timestampSymbol: unique symbol;
|
||||
>timestampSymbol : unique symbol
|
||||
|
||||
export declare const Timestamp: {
|
||||
>Timestamp : { [timestampSymbol]: true; }
|
||||
|
||||
[TKey in typeof timestampSymbol]: true;
|
||||
>timestampSymbol : unique symbol
|
||||
>true : true
|
||||
|
||||
};
|
||||
|
||||
export declare function now(): typeof Timestamp;
|
||||
>now : () => typeof Timestamp
|
||||
>Timestamp : { [timestampSymbol]: true; }
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import * as x from "./a";
|
||||
>x : typeof x
|
||||
|
||||
export const timestamp = x.now();
|
||||
>timestamp : { [x.timestampSymbol]: true; }
|
||||
>x.now() : { [x.timestampSymbol]: true; }
|
||||
>x.now : () => { [x.timestampSymbol]: true; }
|
||||
>x : typeof x
|
||||
>now : () => { [x.timestampSymbol]: true; }
|
||||
|
||||
=== tests/cases/compiler/c.ts ===
|
||||
import { now } from "./a";
|
||||
>now : () => { [timestampSymbol]: true; }
|
||||
|
||||
export const timestamp = now();
|
||||
>timestamp : { [timestampSymbol]: true; }
|
||||
>now() : { [timestampSymbol]: true; }
|
||||
>now : () => { [timestampSymbol]: true; }
|
||||
|
||||
@@ -14,8 +14,8 @@ function Menu<MenuItemVariant extends ListItemVariant = ListItemVariant.OneLine>
|
||||
>data : IData<MenuItemVariant>
|
||||
|
||||
const listItemVariant = data.menuItemsVariant ?? ListItemVariant.OneLine;
|
||||
>listItemVariant : ListItemVariant.OneLine | NonNullable<MenuItemVariant>
|
||||
>data.menuItemsVariant ?? ListItemVariant.OneLine : ListItemVariant.OneLine | NonNullable<MenuItemVariant>
|
||||
>listItemVariant : ListItemVariant.OneLine | MenuItemVariant
|
||||
>data.menuItemsVariant ?? ListItemVariant.OneLine : ListItemVariant.OneLine | MenuItemVariant
|
||||
>data.menuItemsVariant : MenuItemVariant | undefined
|
||||
>data : IData<MenuItemVariant>
|
||||
>menuItemsVariant : MenuItemVariant | undefined
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693: 'string' only refers to a type, but is being used as a value here.
|
||||
tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes
|
||||
|
||||
|
||||
==== tests/cases/compiler/errorLocationForInterfaceExtension.ts (1 errors) ====
|
||||
@@ -6,5 +6,5 @@ tests/cases/compiler/errorLocationForInterfaceExtension.ts(3,21): error TS2693:
|
||||
|
||||
interface x extends string { }
|
||||
~~~~~~
|
||||
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
|
||||
!!! error TS2840: An interface cannot extend a primitive type like 'string'; an interface can only extend named types and classes
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
"containerName": "",
|
||||
"fileName": "/tests/cases/fourslash/findAllRefsRootSymbols.ts",
|
||||
"kind": "property",
|
||||
"name": "(property) x: {} & string",
|
||||
"name": "(property) x: string",
|
||||
"textSpan": {
|
||||
"start": 14,
|
||||
"length": 1
|
||||
@@ -123,26 +123,6 @@
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "{",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "}",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "&",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
@@ -258,7 +238,7 @@
|
||||
"containerName": "",
|
||||
"fileName": "/tests/cases/fourslash/findAllRefsRootSymbols.ts",
|
||||
"kind": "property",
|
||||
"name": "(property) x: {} & string",
|
||||
"name": "(property) x: string",
|
||||
"textSpan": {
|
||||
"start": 14,
|
||||
"length": 1
|
||||
@@ -292,26 +272,6 @@
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "{",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "}",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "&",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
@@ -415,7 +375,7 @@
|
||||
"containerName": "",
|
||||
"fileName": "/tests/cases/fourslash/findAllRefsRootSymbols.ts",
|
||||
"kind": "property",
|
||||
"name": "(property) x: {} & string",
|
||||
"name": "(property) x: string",
|
||||
"textSpan": {
|
||||
"start": 14,
|
||||
"length": 1
|
||||
@@ -449,26 +409,6 @@
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "{",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "}",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "&",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
@@ -725,7 +665,7 @@
|
||||
"containerName": "",
|
||||
"fileName": "/tests/cases/fourslash/findAllRefsRootSymbols.ts",
|
||||
"kind": "property",
|
||||
"name": "(property) x: {} & string",
|
||||
"name": "(property) x: string",
|
||||
"textSpan": {
|
||||
"start": 14,
|
||||
"length": 1
|
||||
@@ -759,26 +699,6 @@
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "{",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "}",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "&",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "string",
|
||||
"kind": "keyword"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(2,5): error TS2339: Property 'toString' does not exist on type 'T'.
|
||||
tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(15,6): error TS2345: Argument of type 'T' is not assignable to parameter of type '{}'.
|
||||
tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(16,6): error TS2345: Argument of type 'T' is not assignable to parameter of type 'Record<string, any>'.
|
||||
tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(17,5): error TS2339: Property 'toString' does not exist on type 'T'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/genericUnboundedTypeParamAssignability.ts (2 errors) ====
|
||||
==== tests/cases/compiler/genericUnboundedTypeParamAssignability.ts (4 errors) ====
|
||||
function f1<T>(o: T) {
|
||||
o.toString(); // error
|
||||
~~~~~~~~
|
||||
@@ -20,7 +22,13 @@ tests/cases/compiler/genericUnboundedTypeParamAssignability.ts(17,5): error TS23
|
||||
function user<T>(t: T) {
|
||||
f1(t);
|
||||
f2(t); // error in strict, unbounded T doesn't satisfy the constraint
|
||||
~
|
||||
!!! error TS2345: Argument of type 'T' is not assignable to parameter of type '{}'.
|
||||
!!! related TS2208 tests/cases/compiler/genericUnboundedTypeParamAssignability.ts:13:15: This type parameter probably needs an `extends object` constraint.
|
||||
f3(t); // error in strict, unbounded T doesn't satisfy the constraint
|
||||
~
|
||||
!!! error TS2345: Argument of type 'T' is not assignable to parameter of type 'Record<string, any>'.
|
||||
!!! related TS2208 tests/cases/compiler/genericUnboundedTypeParamAssignability.ts:13:15: This type parameter probably needs an `extends object` constraint.
|
||||
t.toString(); // error, for the same reason as f1()
|
||||
~~~~~~~~
|
||||
!!! error TS2339: Property 'toString' does not exist on type 'T'.
|
||||
|
||||
@@ -3,12 +3,11 @@ tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(23,12): error TS2361: T
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(27,12): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(34,12): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(53,14): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(55,18): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(60,12): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(64,12): error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
|
||||
|
||||
==== tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts (8 errors) ====
|
||||
==== tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts (7 errors) ====
|
||||
const validHasKey = <T extends object>(
|
||||
thing: T,
|
||||
key: string,
|
||||
@@ -74,8 +73,6 @@ tests/cases/compiler/inDoesNotOperateOnPrimitiveTypes.ts(64,12): error TS2361: T
|
||||
!!! error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
if (typeof p === "object") {
|
||||
"key" in p;
|
||||
~
|
||||
!!! error TS2361: The right-hand side of an 'in' expression must not be a primitive.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ function union5<T extends object | string, U extends object | number>(p: T | U)
|
||||
"key" in p;
|
||||
>"key" in p : boolean
|
||||
>"key" : "key"
|
||||
>p : T | U
|
||||
>p : (T & object) | (U & object)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(14,5): error TS2411: Prop
|
||||
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(15,5): error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to 'string' index type '() => string'.
|
||||
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(19,5): error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to 'string' index type '() => string'.
|
||||
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to 'string' index type '() => string'.
|
||||
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(44,21): error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes
|
||||
tests/cases/compiler/interfacedeclWithIndexerErrors.ts(48,18): error TS2693: 'string' only refers to a type, but is being used as a value here.
|
||||
|
||||
|
||||
==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (5 errors) ====
|
||||
==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (7 errors) ====
|
||||
interface a0 {
|
||||
(): string;
|
||||
(a, b, c?: string): number;
|
||||
@@ -59,6 +61,17 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Prop
|
||||
interface d extends a {
|
||||
}
|
||||
|
||||
interface e extends number {
|
||||
~~~~~~
|
||||
!!! error TS2840: An interface cannot extend a primitive type like 'number'; an interface can only extend named types and classes
|
||||
}
|
||||
|
||||
interface f {
|
||||
prop: typeof string;
|
||||
~~~~~~
|
||||
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
|
||||
}
|
||||
|
||||
class c1 implements a {
|
||||
}
|
||||
var instance2 = new c1();
|
||||
@@ -42,6 +42,13 @@ interface c extends a, b {
|
||||
interface d extends a {
|
||||
}
|
||||
|
||||
interface e extends number {
|
||||
}
|
||||
|
||||
interface f {
|
||||
prop: typeof string;
|
||||
}
|
||||
|
||||
class c1 implements a {
|
||||
}
|
||||
var instance2 = new c1();
|
||||
|
||||
@@ -84,11 +84,22 @@ interface d extends a {
|
||||
>a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1))
|
||||
}
|
||||
|
||||
interface e extends number {
|
||||
>e : Symbol(e, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
|
||||
}
|
||||
|
||||
interface f {
|
||||
>f : Symbol(f, Decl(interfacedeclWithIndexerErrors.ts, 44, 1))
|
||||
|
||||
prop: typeof string;
|
||||
>prop : Symbol(f.prop, Decl(interfacedeclWithIndexerErrors.ts, 46, 13))
|
||||
}
|
||||
|
||||
class c1 implements a {
|
||||
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
|
||||
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1))
|
||||
>a : Symbol(a, Decl(interfacedeclWithIndexerErrors.ts, 29, 1))
|
||||
}
|
||||
var instance2 = new c1();
|
||||
>instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 45, 3))
|
||||
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 41, 1))
|
||||
>instance2 : Symbol(instance2, Decl(interfacedeclWithIndexerErrors.ts, 52, 3))
|
||||
>c1 : Symbol(c1, Decl(interfacedeclWithIndexerErrors.ts, 48, 1))
|
||||
|
||||
|
||||
@@ -70,6 +70,15 @@ interface c extends a, b {
|
||||
interface d extends a {
|
||||
}
|
||||
|
||||
interface e extends number {
|
||||
}
|
||||
|
||||
interface f {
|
||||
prop: typeof string;
|
||||
>prop : any
|
||||
>string : any
|
||||
}
|
||||
|
||||
class c1 implements a {
|
||||
>c1 : c1
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ function inGeneric<T extends A2 | B2>(alsoShouldBeB: T & B2) {
|
||||
|
||||
const b: B2 = alsoShouldBeB;
|
||||
>b : B2
|
||||
>alsoShouldBeB : T & B2
|
||||
>alsoShouldBeB : B2
|
||||
}
|
||||
|
||||
// Repro from #38542
|
||||
@@ -374,6 +374,6 @@ function bar<T extends CA | CB>(x: T & CA) {
|
||||
|
||||
let ab: ABI = x;
|
||||
>ab : ABI
|
||||
>x : T & CA
|
||||
>x : CA
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'T & U' is not assignable to type 'string | number'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'T & U' is not assignable to type 'string | null'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'T & U' is not assignable to type 'number | null'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'string | undefined' is not assignable to type 'string | number'.
|
||||
Type 'undefined' is not assignable to type 'string | number'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'string | undefined' is not assignable to type 'string | null'.
|
||||
Type 'undefined' is not assignable to type 'string | null'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'string | undefined' is not assignable to type 'number | null'.
|
||||
Type 'undefined' is not assignable to type 'number | null'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'.
|
||||
Type 'string' is not assignable to type 'null | undefined'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts (5 errors) ====
|
||||
@@ -14,20 +19,25 @@ tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12
|
||||
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
|
||||
let y1: string | number = x; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'T & U' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'.
|
||||
let y2: string | null = x; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'T & U' is not assignable to type 'string | null'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | null'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'.
|
||||
let y3: string | undefined = x;
|
||||
let y4: number | null = x; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'T & U' is not assignable to type 'number | null'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | null'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'.
|
||||
let y5: number | undefined = x; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
let y6: null | undefined = x; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
|
||||
!!! error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'null | undefined'.
|
||||
}
|
||||
|
||||
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
|
||||
|
||||
@@ -6,7 +6,7 @@ function f1<T extends string | number, U extends string | number>(x: T & U) {
|
||||
// Combined constraint of 'T & U' is 'string | number'
|
||||
let y: string | number = x;
|
||||
>y : string | number
|
||||
>x : T & U
|
||||
>x : string | number
|
||||
}
|
||||
|
||||
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
|
||||
@@ -16,30 +16,30 @@ function f2<T extends string | number | undefined, U extends string | null | und
|
||||
|
||||
let y1: string | number = x; // Error
|
||||
>y1 : string | number
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
|
||||
let y2: string | null = x; // Error
|
||||
>y2 : string | null
|
||||
>null : null
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
|
||||
let y3: string | undefined = x;
|
||||
>y3 : string | undefined
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
|
||||
let y4: number | null = x; // Error
|
||||
>y4 : number | null
|
||||
>null : null
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
|
||||
let y5: number | undefined = x; // Error
|
||||
>y5 : number | undefined
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
|
||||
let y6: null | undefined = x; // Error
|
||||
>y6 : null | undefined
|
||||
>null : null
|
||||
>x : T & U
|
||||
>x : string | undefined
|
||||
}
|
||||
|
||||
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
|
||||
@@ -52,7 +52,7 @@ function f3<T extends string | number | undefined>(x: T & (number | object | und
|
||||
|
||||
const y: number | undefined = x;
|
||||
>y : number | undefined
|
||||
>x : T & (number | object | undefined)
|
||||
>x : number | undefined
|
||||
}
|
||||
|
||||
function f4<T extends string | number>(x: T & (number | object)) {
|
||||
@@ -61,7 +61,7 @@ function f4<T extends string | number>(x: T & (number | object)) {
|
||||
|
||||
const y: number = x;
|
||||
>y : number
|
||||
>x : T & (number | object)
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f5<T, U extends keyof T>(x: keyof T & U) {
|
||||
@@ -70,7 +70,7 @@ function f5<T, U extends keyof T>(x: keyof T & U) {
|
||||
|
||||
let y: keyof any = x;
|
||||
>y : string | number | symbol
|
||||
>x : keyof T & U
|
||||
>x : string | number | symbol
|
||||
}
|
||||
|
||||
// Repro from #23648
|
||||
|
||||
@@ -26,10 +26,10 @@ let x04: A & B & C;
|
||||
>x04 : A & B
|
||||
|
||||
let x05: string & C;
|
||||
>x05 : string & C
|
||||
>x05 : string
|
||||
|
||||
let x06: C & string;
|
||||
>x06 : C & string
|
||||
>x06 : string
|
||||
|
||||
let x07: C;
|
||||
>x07 : C
|
||||
|
||||
@@ -0,0 +1,677 @@
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(316,5): error TS2322: Type 'T' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(317,5): error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
|
||||
Type 'T[string]' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to type '{}'.
|
||||
Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts (3 errors) ====
|
||||
class Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
class TaggedShape extends Shape {
|
||||
tag: string;
|
||||
}
|
||||
|
||||
class Item {
|
||||
name: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
class Options {
|
||||
visible: "yes" | "no";
|
||||
}
|
||||
|
||||
type Dictionary<T> = { [x: string]: T };
|
||||
type NumericallyIndexed<T> = { [x: number]: T };
|
||||
|
||||
const enum E { A, B, C }
|
||||
|
||||
type K00 = keyof any; // string
|
||||
type K01 = keyof string; // "toString" | "charAt" | ...
|
||||
type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ...
|
||||
type K03 = keyof boolean; // "valueOf"
|
||||
type K04 = keyof void; // never
|
||||
type K05 = keyof undefined; // never
|
||||
type K06 = keyof null; // never
|
||||
type K07 = keyof never; // string | number | symbol
|
||||
type K08 = keyof unknown; // never
|
||||
|
||||
type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
|
||||
type K11 = keyof Shape[]; // "length" | "toString" | ...
|
||||
type K12 = keyof Dictionary<Shape>; // string
|
||||
type K13 = keyof {}; // never
|
||||
type K14 = keyof Object; // "constructor" | "toString" | ...
|
||||
type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
|
||||
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
|
||||
type K17 = keyof (Shape | Item); // "name"
|
||||
type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price"
|
||||
type K19 = keyof NumericallyIndexed<Shape> // never
|
||||
|
||||
type KeyOf<T> = keyof T;
|
||||
|
||||
type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible"
|
||||
type K21 = KeyOf<Dictionary<Shape>>; // string
|
||||
|
||||
type NAME = "name";
|
||||
type WIDTH_OR_HEIGHT = "width" | "height";
|
||||
|
||||
type Q10 = Shape["name"]; // string
|
||||
type Q11 = Shape["width" | "height"]; // number
|
||||
type Q12 = Shape["name" | "visible"]; // string | boolean
|
||||
|
||||
type Q20 = Shape[NAME]; // string
|
||||
type Q21 = Shape[WIDTH_OR_HEIGHT]; // number
|
||||
|
||||
type Q30 = [string, number][0]; // string
|
||||
type Q31 = [string, number][1]; // number
|
||||
type Q32 = [string, number][number]; // string | number
|
||||
type Q33 = [string, number][E.A]; // string
|
||||
type Q34 = [string, number][E.B]; // number
|
||||
type Q35 = [string, number]["0"]; // string
|
||||
type Q36 = [string, number]["1"]; // string
|
||||
|
||||
type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no"
|
||||
type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no"
|
||||
|
||||
type Q50 = Dictionary<Shape>["howdy"]; // Shape
|
||||
type Q51 = Dictionary<Shape>[123]; // Shape
|
||||
type Q52 = Dictionary<Shape>[E.B]; // Shape
|
||||
|
||||
declare let cond: boolean;
|
||||
|
||||
function getProperty<T, K extends keyof T>(obj: T, key: K) {
|
||||
return obj[key];
|
||||
}
|
||||
|
||||
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) {
|
||||
obj[key] = value;
|
||||
}
|
||||
|
||||
function f10(shape: Shape) {
|
||||
let name = getProperty(shape, "name"); // string
|
||||
let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number
|
||||
let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean
|
||||
setProperty(shape, "name", "rectangle");
|
||||
setProperty(shape, cond ? "width" : "height", 10);
|
||||
setProperty(shape, cond ? "name" : "visible", true); // Technically not safe
|
||||
}
|
||||
|
||||
function f11(a: Shape[]) {
|
||||
let len = getProperty(a, "length"); // number
|
||||
setProperty(a, "length", len);
|
||||
}
|
||||
|
||||
function f12(t: [Shape, boolean]) {
|
||||
let len = getProperty(t, "length");
|
||||
let s2 = getProperty(t, "0"); // Shape
|
||||
let b2 = getProperty(t, "1"); // boolean
|
||||
}
|
||||
|
||||
function f13(foo: any, bar: any) {
|
||||
let x = getProperty(foo, "x"); // any
|
||||
let y = getProperty(foo, "100"); // any
|
||||
let z = getProperty(foo, bar); // any
|
||||
}
|
||||
|
||||
class Component<PropType> {
|
||||
props: PropType;
|
||||
getProperty<K extends keyof PropType>(key: K) {
|
||||
return this.props[key];
|
||||
}
|
||||
setProperty<K extends keyof PropType>(key: K, value: PropType[K]) {
|
||||
this.props[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function f20(component: Component<Shape>) {
|
||||
let name = component.getProperty("name"); // string
|
||||
let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number
|
||||
let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean
|
||||
component.setProperty("name", "rectangle");
|
||||
component.setProperty(cond ? "width" : "height", 10)
|
||||
component.setProperty(cond ? "name" : "visible", true); // Technically not safe
|
||||
}
|
||||
|
||||
function pluck<T, K extends keyof T>(array: T[], key: K) {
|
||||
return array.map(x => x[key]);
|
||||
}
|
||||
|
||||
function f30(shapes: Shape[]) {
|
||||
let names = pluck(shapes, "name"); // string[]
|
||||
let widths = pluck(shapes, "width"); // number[]
|
||||
let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[]
|
||||
}
|
||||
|
||||
function f31<K extends keyof Shape>(key: K) {
|
||||
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
|
||||
return shape[key]; // Shape[K]
|
||||
}
|
||||
|
||||
function f32<K extends "width" | "height">(key: K) {
|
||||
const shape: Shape = { name: "foo", width: 5, height: 10, visible: true };
|
||||
return shape[key]; // Shape[K]
|
||||
}
|
||||
|
||||
function f33<S extends Shape, K extends keyof S>(shape: S, key: K) {
|
||||
let name = getProperty(shape, "name");
|
||||
let prop = getProperty(shape, key);
|
||||
return prop;
|
||||
}
|
||||
|
||||
function f34(ts: TaggedShape) {
|
||||
let tag1 = f33(ts, "tag");
|
||||
let tag2 = getProperty(ts, "tag");
|
||||
}
|
||||
|
||||
class C {
|
||||
public x: string;
|
||||
protected y: string;
|
||||
private z: string;
|
||||
}
|
||||
|
||||
// Indexed access expressions have always permitted access to private and protected members.
|
||||
// For consistency we also permit such access in indexed access types.
|
||||
function f40(c: C) {
|
||||
type X = C["x"];
|
||||
type Y = C["y"];
|
||||
type Z = C["z"];
|
||||
let x: X = c["x"];
|
||||
let y: Y = c["y"];
|
||||
let z: Z = c["z"];
|
||||
}
|
||||
|
||||
function f50<T>(k: keyof T, s: string) {
|
||||
const x1 = s as keyof T;
|
||||
const x2 = k as string;
|
||||
}
|
||||
|
||||
function f51<T, K extends keyof T>(k: K, s: string) {
|
||||
const x1 = s as keyof T;
|
||||
const x2 = k as string;
|
||||
}
|
||||
|
||||
function f52<T>(obj: { [x: string]: boolean }, k: Exclude<keyof T, symbol>, s: string, n: number) {
|
||||
const x1 = obj[s];
|
||||
const x2 = obj[n];
|
||||
const x3 = obj[k];
|
||||
}
|
||||
|
||||
function f53<T, K extends Exclude<keyof T, symbol>>(obj: { [x: string]: boolean }, k: K, s: string, n: number) {
|
||||
const x1 = obj[s];
|
||||
const x2 = obj[n];
|
||||
const x3 = obj[k];
|
||||
}
|
||||
|
||||
function f54<T>(obj: T, key: keyof T) {
|
||||
for (let s in obj[key]) {
|
||||
}
|
||||
const b = "foo" in obj[key];
|
||||
}
|
||||
|
||||
function f55<T, K extends keyof T>(obj: T, key: K) {
|
||||
for (let s in obj[key]) {
|
||||
}
|
||||
const b = "foo" in obj[key];
|
||||
}
|
||||
|
||||
function f60<T>(source: T, target: T) {
|
||||
for (let k in source) {
|
||||
target[k] = source[k];
|
||||
}
|
||||
}
|
||||
|
||||
function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
|
||||
func<{ a: any, b: any }, { a: any, c: any }>('a', 'a');
|
||||
func<{ a: any, b: any }, { a: any, c: any }>('a', 'b');
|
||||
func<{ a: any, b: any }, { a: any, c: any }>('a', 'c');
|
||||
}
|
||||
|
||||
function f71(func: <T, U>(x: T, y: U) => Partial<T & U>) {
|
||||
let x = func({ a: 1, b: "hello" }, { c: true });
|
||||
x.a; // number | undefined
|
||||
x.b; // string | undefined
|
||||
x.c; // boolean | undefined
|
||||
}
|
||||
|
||||
function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]) {
|
||||
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
|
||||
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
|
||||
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
|
||||
}
|
||||
|
||||
function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]) {
|
||||
let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number
|
||||
let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string
|
||||
let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean
|
||||
}
|
||||
|
||||
function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) {
|
||||
let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number
|
||||
let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean
|
||||
}
|
||||
|
||||
function f80<T extends { a: { x: any } }>(obj: T) {
|
||||
let a1 = obj.a; // { x: any }
|
||||
let a2 = obj['a']; // { x: any }
|
||||
let a3 = obj['a'] as T['a']; // T["a"]
|
||||
let x1 = obj.a.x; // any
|
||||
let x2 = obj['a']['x']; // any
|
||||
let x3 = obj['a']['x'] as T['a']['x']; // T["a"]["x"]
|
||||
}
|
||||
|
||||
function f81<T extends { a: { x: any } }>(obj: T) {
|
||||
return obj['a']['x'] as T['a']['x'];
|
||||
}
|
||||
|
||||
function f82() {
|
||||
let x1 = f81({ a: { x: "hello" } }); // string
|
||||
let x2 = f81({ a: { x: 42 } }); // number
|
||||
}
|
||||
|
||||
function f83<T extends { [x: string]: { x: any } }, K extends keyof T>(obj: T, key: K) {
|
||||
return obj[key]['x'] as T[K]['x'];
|
||||
}
|
||||
|
||||
function f84() {
|
||||
let x1 = f83({ foo: { x: "hello" } }, "foo"); // string
|
||||
let x2 = f83({ bar: { x: 42 } }, "bar"); // number
|
||||
}
|
||||
|
||||
class C1 {
|
||||
x: number;
|
||||
get<K extends keyof this>(key: K) {
|
||||
return this[key];
|
||||
}
|
||||
set<K extends keyof this>(key: K, value: this[K]) {
|
||||
this[key] = value;
|
||||
}
|
||||
foo() {
|
||||
let x1 = this.x; // number
|
||||
let x2 = this["x"]; // number
|
||||
let x3 = this.get("x"); // this["x"]
|
||||
let x4 = getProperty(this, "x"); // this["x"]
|
||||
this.x = 42;
|
||||
this["x"] = 42;
|
||||
this.set("x", 42);
|
||||
setProperty(this, "x", 42);
|
||||
}
|
||||
}
|
||||
|
||||
type S2 = {
|
||||
a: string;
|
||||
b: string;
|
||||
};
|
||||
|
||||
function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K]) {
|
||||
x1 = x2;
|
||||
x1 = x3;
|
||||
x2 = x1;
|
||||
x2 = x3;
|
||||
x3 = x1;
|
||||
x3 = x2;
|
||||
x1.length;
|
||||
x2.length;
|
||||
x3.length;
|
||||
}
|
||||
|
||||
function f91<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) {
|
||||
let a: {};
|
||||
a = x;
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type '{}'.
|
||||
!!! related TS2208 tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts:314:14: This type parameter probably needs an `extends object` constraint.
|
||||
a = y;
|
||||
~
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type '{}'.
|
||||
a = z;
|
||||
~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
}
|
||||
|
||||
function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) {
|
||||
let a: {} | null | undefined;
|
||||
a = x;
|
||||
a = y;
|
||||
a = z;
|
||||
}
|
||||
|
||||
// Repros from #12011
|
||||
|
||||
class Base {
|
||||
get<K extends keyof this>(prop: K) {
|
||||
return this[prop];
|
||||
}
|
||||
set<K extends keyof this>(prop: K, value: this[K]) {
|
||||
this[prop] = value;
|
||||
}
|
||||
}
|
||||
|
||||
class Person extends Base {
|
||||
parts: number;
|
||||
constructor(parts: number) {
|
||||
super();
|
||||
this.set("parts", parts);
|
||||
}
|
||||
getParts() {
|
||||
return this.get("parts")
|
||||
}
|
||||
}
|
||||
|
||||
class OtherPerson {
|
||||
parts: number;
|
||||
constructor(parts: number) {
|
||||
setProperty(this, "parts", parts);
|
||||
}
|
||||
getParts() {
|
||||
return getProperty(this, "parts")
|
||||
}
|
||||
}
|
||||
|
||||
// Modified repro from #12544
|
||||
|
||||
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
|
||||
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
|
||||
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
|
||||
function path(obj: any, ...keys: (string | number)[]): any;
|
||||
function path(obj: any, ...keys: (string | number)[]): any {
|
||||
let result = obj;
|
||||
for (let k of keys) {
|
||||
result = result[k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
type Thing = {
|
||||
a: { x: number, y: string },
|
||||
b: boolean
|
||||
};
|
||||
|
||||
|
||||
function f1(thing: Thing) {
|
||||
let x1 = path(thing, 'a'); // { x: number, y: string }
|
||||
let x2 = path(thing, 'a', 'y'); // string
|
||||
let x3 = path(thing, 'b'); // boolean
|
||||
let x4 = path(thing, ...['a', 'x']); // any
|
||||
}
|
||||
|
||||
// Repro from comment in #12114
|
||||
|
||||
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
|
||||
(value: T[K1][K2]) => object[key1][key2] = value;
|
||||
|
||||
// Modified repro from #12573
|
||||
|
||||
declare function one<T>(handler: (t: T) => void): T
|
||||
var empty = one(() => {}) // inferred as {}, expected
|
||||
|
||||
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
|
||||
declare function on<T>(handlerHash: Handlers<T>): T
|
||||
var hashOfEmpty1 = on({ test: () => {} }); // {}
|
||||
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
|
||||
|
||||
// Repro from #12624
|
||||
|
||||
interface Options1<Data, Computed> {
|
||||
data?: Data
|
||||
computed?: Computed;
|
||||
}
|
||||
|
||||
declare class Component1<Data, Computed> {
|
||||
constructor(options: Options1<Data, Computed>);
|
||||
get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K];
|
||||
}
|
||||
|
||||
let c1 = new Component1({
|
||||
data: {
|
||||
hello: ""
|
||||
}
|
||||
});
|
||||
|
||||
c1.get("hello");
|
||||
|
||||
// Repro from #12625
|
||||
|
||||
interface Options2<Data, Computed> {
|
||||
data?: Data
|
||||
computed?: Computed;
|
||||
}
|
||||
|
||||
declare class Component2<Data, Computed> {
|
||||
constructor(options: Options2<Data, Computed>);
|
||||
get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K];
|
||||
}
|
||||
|
||||
// Repro from #12641
|
||||
|
||||
interface R {
|
||||
p: number;
|
||||
}
|
||||
|
||||
function f<K extends keyof R>(p: K) {
|
||||
let a: any;
|
||||
a[p].add; // any
|
||||
}
|
||||
|
||||
// Repro from #12651
|
||||
|
||||
type MethodDescriptor = {
|
||||
name: string;
|
||||
args: any[];
|
||||
returnValue: any;
|
||||
}
|
||||
|
||||
declare function dispatchMethod<M extends MethodDescriptor>(name: M['name'], args: M['args']): M['returnValue'];
|
||||
|
||||
type SomeMethodDescriptor = {
|
||||
name: "someMethod";
|
||||
args: [string, number];
|
||||
returnValue: string[];
|
||||
}
|
||||
|
||||
let result = dispatchMethod<SomeMethodDescriptor>("someMethod", ["hello", 35]);
|
||||
|
||||
// Repro from #13073
|
||||
|
||||
type KeyTypes = "a" | "b"
|
||||
let MyThingy: { [key in KeyTypes]: string[] };
|
||||
|
||||
function addToMyThingy<S extends KeyTypes>(key: S) {
|
||||
MyThingy[key].push("a");
|
||||
}
|
||||
|
||||
// Repro from #13102
|
||||
|
||||
type Handler<T> = {
|
||||
onChange: (name: keyof T) => void;
|
||||
};
|
||||
|
||||
function onChangeGenericFunction<T>(handler: Handler<T & {preset: number}>) {
|
||||
handler.onChange('preset')
|
||||
}
|
||||
|
||||
// Repro from #13285
|
||||
|
||||
function updateIds<T extends Record<K, string>, K extends string>(
|
||||
obj: T,
|
||||
idFields: K[],
|
||||
idMapping: Partial<Record<T[K], T[K]>>
|
||||
): Record<K, string> {
|
||||
for (const idField of idFields) {
|
||||
const newId: T[K] | undefined = idMapping[obj[idField]];
|
||||
if (newId) {
|
||||
obj[idField] = newId;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Repro from #13285
|
||||
|
||||
function updateIds2<T extends { [x: string]: string }, K extends keyof T>(
|
||||
obj: T,
|
||||
key: K,
|
||||
stringMap: { [oldId: string]: string }
|
||||
) {
|
||||
var x = obj[key];
|
||||
stringMap[x]; // Should be OK.
|
||||
}
|
||||
|
||||
// Repro from #13514
|
||||
|
||||
declare function head<T extends Array<any>>(list: T): T[0];
|
||||
|
||||
// Repro from #13604
|
||||
|
||||
class A<T> {
|
||||
props: T & { foo: string };
|
||||
}
|
||||
|
||||
class B extends A<{ x: number}> {
|
||||
f(p: this["props"]) {
|
||||
p.x;
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #13749
|
||||
|
||||
class Form<T> {
|
||||
private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>}
|
||||
|
||||
public set<K extends keyof T>(prop: K, value: T[K]) {
|
||||
this.childFormFactories[prop](value)
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #13787
|
||||
|
||||
class SampleClass<P> {
|
||||
public props: Readonly<P>;
|
||||
constructor(props: P) {
|
||||
this.props = Object.freeze(props);
|
||||
}
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
declare function merge<T, U>(obj1: T, obj2: U): T & U;
|
||||
|
||||
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
|
||||
constructor(props: T) {
|
||||
const foo: Foo = { foo: "bar" };
|
||||
super(merge(props, foo));
|
||||
}
|
||||
|
||||
public brokenMethod() {
|
||||
this.props.foo.concat;
|
||||
}
|
||||
}
|
||||
new AnotherSampleClass({});
|
||||
|
||||
// Positive repro from #17166
|
||||
function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
}
|
||||
}
|
||||
|
||||
// # 21185
|
||||
type Predicates<TaggedRecord> = {
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
|
||||
}
|
||||
|
||||
// Repros from #23592
|
||||
|
||||
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
|
||||
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
|
||||
|
||||
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
|
||||
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
|
||||
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
|
||||
|
||||
// Repro from #23618
|
||||
|
||||
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
|
||||
enum Flag {
|
||||
FLAG_1 = "flag_1",
|
||||
FLAG_2 = "flag_2"
|
||||
}
|
||||
|
||||
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
|
||||
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
|
||||
return record[flags[0]];
|
||||
}
|
||||
|
||||
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
|
||||
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
|
||||
return record[flags[0]];
|
||||
}
|
||||
|
||||
// Repro from #21368
|
||||
|
||||
interface I {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
declare function take<T>(p: T): void;
|
||||
|
||||
function fn<T extends I, K extends keyof T>(o: T, k: K) {
|
||||
take<{} | null | undefined>(o[k]);
|
||||
take<any>(o[k]);
|
||||
}
|
||||
|
||||
// Repro from #23133
|
||||
|
||||
class Unbounded<T> {
|
||||
foo(x: T[keyof T]) {
|
||||
let y: {} | undefined | null = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #23940
|
||||
|
||||
interface I7 {
|
||||
x: any;
|
||||
}
|
||||
type Foo7<T extends number> = T;
|
||||
declare function f7<K extends keyof I7>(type: K): Foo7<I7[K]>;
|
||||
|
||||
// Repro from #21770
|
||||
|
||||
type Dict<T extends string> = { [key in T]: number };
|
||||
type DictDict<V extends string, T extends string> = { [key in V]: Dict<T> };
|
||||
|
||||
function ff1<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number {
|
||||
return dd[k1][k2];
|
||||
}
|
||||
|
||||
function ff2<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number {
|
||||
const d: Dict<T> = dd[k1];
|
||||
return d[k2];
|
||||
}
|
||||
|
||||
// Repro from #26409
|
||||
|
||||
const cf1 = <T extends { [P in K]: string; } & { cool: string; }, K extends keyof T>(t: T, k: K) =>
|
||||
{
|
||||
const s: string = t[k];
|
||||
t.cool;
|
||||
};
|
||||
|
||||
const cf2 = <T extends { [P in K | "cool"]: string; }, K extends keyof T>(t: T, k: K) =>
|
||||
{
|
||||
const s: string = t[k];
|
||||
t.cool;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts(12,9): error TS2322: Type 'T' is not assignable to type 'Modify<T>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts(22,9): error TS2322: Type 'T' is not assignable to type 'ModifyInclOpt<T>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts(23,9): error TS2322: Type 'T' is not assignable to type 'FilterExclOpt<T>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts(24,9): error TS2322: Type 'T' is not assignable to type 'ModifyExclOpt<T>'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts (3 errors) ====
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts (4 errors) ====
|
||||
// From original issue #45212:
|
||||
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
|
||||
type H<T> = T[keyof Methods<T>]; // Ok
|
||||
@@ -28,6 +29,8 @@ tests/cases/conformance/types/mapped/mappedTypeAsClauseRelationships.ts(24,9): e
|
||||
function fun2<T>(val: T) {
|
||||
let x: FilterInclOpt<T> = val; // Ok
|
||||
let y: ModifyInclOpt<T> = val; // Ok
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'ModifyInclOpt<T>'.
|
||||
let z: FilterExclOpt<T> = val; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'FilterExclOpt<T>'.
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//// [mappedTypeGenericIndexedAccess.ts]
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
first: { a1: true };
|
||||
second: { a2: true };
|
||||
third: { a3: true };
|
||||
}
|
||||
|
||||
class Test {
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
if (!this.entries[name]) {
|
||||
this.entries[name] = [];
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
[0]: { foo: 'bar'; };
|
||||
[1]: { a: 'b'; };
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
|
||||
type TypeHandlers = {
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
[0]: (p) => console.log(p.foo),
|
||||
[1]: (p) => console.log(p.a),
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
typeHandlers[p.t]?.(p);
|
||||
|
||||
|
||||
//// [mappedTypeGenericIndexedAccess.js]
|
||||
"use strict";
|
||||
// Repro from #49242
|
||||
var _a;
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
this.entries = {};
|
||||
}
|
||||
Test.prototype.addEntry = function (name, entry) {
|
||||
var _a;
|
||||
if (!this.entries[name]) {
|
||||
this.entries[name] = [];
|
||||
}
|
||||
(_a = this.entries[name]) === null || _a === void 0 ? void 0 : _a.push(entry);
|
||||
};
|
||||
return Test;
|
||||
}());
|
||||
var typeHandlers = (_a = {},
|
||||
_a[0] = function (p) { return console.log(p.foo); },
|
||||
_a[1] = function (p) { return console.log(p.a); },
|
||||
_a);
|
||||
var onSomeEvent = function (p) { var _a; return (_a = typeHandlers[p.t]) === null || _a === void 0 ? void 0 : _a.call(typeHandlers, p); };
|
||||
|
||||
|
||||
//// [mappedTypeGenericIndexedAccess.d.ts]
|
||||
declare type Types = {
|
||||
first: {
|
||||
a1: true;
|
||||
};
|
||||
second: {
|
||||
a2: true;
|
||||
};
|
||||
third: {
|
||||
a3: true;
|
||||
};
|
||||
};
|
||||
declare class Test {
|
||||
entries: {
|
||||
[T in keyof Types]?: Types[T][];
|
||||
};
|
||||
constructor();
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]): void;
|
||||
}
|
||||
declare type TypesMap = {
|
||||
[0]: {
|
||||
foo: 'bar';
|
||||
};
|
||||
[1]: {
|
||||
a: 'b';
|
||||
};
|
||||
};
|
||||
declare type P<T extends keyof TypesMap> = {
|
||||
t: T;
|
||||
} & TypesMap[T];
|
||||
declare type TypeHandlers = {
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
};
|
||||
declare const typeHandlers: TypeHandlers;
|
||||
declare const onSomeEvent: <T extends keyof TypesMap>(p: P<T>) => void | undefined;
|
||||
@@ -0,0 +1,150 @@
|
||||
=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts ===
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
|
||||
first: { a1: true };
|
||||
>first : Symbol(first, Decl(mappedTypeGenericIndexedAccess.ts, 2, 14))
|
||||
>a1 : Symbol(a1, Decl(mappedTypeGenericIndexedAccess.ts, 3, 12))
|
||||
|
||||
second: { a2: true };
|
||||
>second : Symbol(second, Decl(mappedTypeGenericIndexedAccess.ts, 3, 24))
|
||||
>a2 : Symbol(a2, Decl(mappedTypeGenericIndexedAccess.ts, 4, 13))
|
||||
|
||||
third: { a3: true };
|
||||
>third : Symbol(third, Decl(mappedTypeGenericIndexedAccess.ts, 4, 25))
|
||||
>a3 : Symbol(a3, Decl(mappedTypeGenericIndexedAccess.ts, 5, 12))
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16))
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
>addEntry : Symbol(Test.addEntry, Decl(mappedTypeGenericIndexedAccess.ts, 13, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
|
||||
if (!this.entries[name]) {
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
|
||||
this.entries[name] = [];
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
>this.entries[name]?.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
|
||||
[0]: { foo: 'bar'; };
|
||||
>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17))
|
||||
>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17))
|
||||
>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
|
||||
[1]: { a: 'b'; };
|
||||
>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25))
|
||||
>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25))
|
||||
>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
|
||||
type TypeHandlers = {
|
||||
>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59))
|
||||
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 33, 29))
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5))
|
||||
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5))
|
||||
>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59))
|
||||
|
||||
[0]: (p) => console.log(p.foo),
|
||||
>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36))
|
||||
>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>p.foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10))
|
||||
>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
|
||||
[1]: (p) => console.log(p.a),
|
||||
>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35))
|
||||
>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>p.a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10))
|
||||
>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
>onSomeEvent : Symbol(onSomeEvent, Decl(mappedTypeGenericIndexedAccess.ts, 41, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21))
|
||||
|
||||
typeHandlers[p.t]?.(p);
|
||||
>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5))
|
||||
>p.t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts ===
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
>Types : { first: { a1: true;}; second: { a2: true;}; third: { a3: true;}; }
|
||||
|
||||
first: { a1: true };
|
||||
>first : { a1: true; }
|
||||
>a1 : true
|
||||
>true : true
|
||||
|
||||
second: { a2: true };
|
||||
>second : { a2: true; }
|
||||
>a2 : true
|
||||
>true : true
|
||||
|
||||
third: { a3: true };
|
||||
>third : { a3: true; }
|
||||
>a3 : true
|
||||
>true : true
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
>this.entries = {} : {}
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>{} : {}
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
>addEntry : <T extends keyof Types>(name: T, entry: Types[T]) => void
|
||||
>name : T
|
||||
>entry : Types[T]
|
||||
|
||||
if (!this.entries[name]) {
|
||||
>!this.entries[name] : boolean
|
||||
>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T]
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
|
||||
this.entries[name] = [];
|
||||
>this.entries[name] = [] : never[]
|
||||
>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T]
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
>[] : never[]
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
>this.entries[name]?.push(entry) : number | undefined
|
||||
>this.entries[name]?.push : ((...items: Types[T][]) => number) | undefined
|
||||
>this.entries[name] : Types[T][] | undefined
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
>push : ((...items: Types[T][]) => number) | undefined
|
||||
>entry : Types[T]
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
>TypesMap : { 0: { foo: 'bar';}; 1: { a: 'b';}; }
|
||||
|
||||
[0]: { foo: 'bar'; };
|
||||
>[0] : { foo: 'bar'; }
|
||||
>0 : 0
|
||||
>foo : "bar"
|
||||
|
||||
[1]: { a: 'b'; };
|
||||
>[1] : { a: 'b'; }
|
||||
>1 : 1
|
||||
>a : "b"
|
||||
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
>P : P<T>
|
||||
>t : T
|
||||
|
||||
type TypeHandlers = {
|
||||
>TypeHandlers : { 0?: ((p: P<0>) => void) | undefined; 1?: ((p: P<1>) => void) | undefined; }
|
||||
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
>p : P<T>
|
||||
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
>typeHandlers : TypeHandlers
|
||||
>{ [0]: (p) => console.log(p.foo), [1]: (p) => console.log(p.a),} : { 0: (p: P<0>) => void; 1: (p: P<1>) => void; }
|
||||
|
||||
[0]: (p) => console.log(p.foo),
|
||||
>[0] : (p: P<0>) => void
|
||||
>0 : 0
|
||||
>(p) => console.log(p.foo) : (p: P<0>) => void
|
||||
>p : P<0>
|
||||
>console.log(p.foo) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>p.foo : "bar"
|
||||
>p : P<0>
|
||||
>foo : "bar"
|
||||
|
||||
[1]: (p) => console.log(p.a),
|
||||
>[1] : (p: P<1>) => void
|
||||
>1 : 1
|
||||
>(p) => console.log(p.a) : (p: P<1>) => void
|
||||
>p : P<1>
|
||||
>console.log(p.a) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>p.a : "b"
|
||||
>p : P<1>
|
||||
>a : "b"
|
||||
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
>onSomeEvent : <T extends keyof TypesMap>(p: P<T>) => void | undefined
|
||||
><T extends keyof TypesMap>(p: P<T>) => typeHandlers[p.t]?.(p) : <T extends keyof TypesMap>(p: P<T>) => void | undefined
|
||||
>p : P<T>
|
||||
|
||||
typeHandlers[p.t]?.(p);
|
||||
>typeHandlers[p.t]?.(p) : void | undefined
|
||||
>typeHandlers[p.t] : ((p: P<T>) => void) | undefined
|
||||
>typeHandlers : TypeHandlers
|
||||
>p.t : T
|
||||
>p : { t: T; } & ({ foo: "bar"; } | { a: "b"; })
|
||||
>t : T
|
||||
>p : P<T>
|
||||
|
||||
@@ -27,17 +27,17 @@ function boxify<T>(obj: T): Boxified<T> {
|
||||
|
||||
for (let k in obj) {
|
||||
>k : Extract<keyof T, string>
|
||||
>obj : T
|
||||
>obj : (T & null) | (T & object)
|
||||
|
||||
result[k] = { value: obj[k] };
|
||||
>result[k] = { value: obj[k] } : { value: T[Extract<keyof T, string>]; }
|
||||
>result[k] = { value: obj[k] } : { value: (T & object)[Extract<keyof T, string>]; }
|
||||
>result[k] : Boxified<T>[Extract<keyof T, string>]
|
||||
>result : Boxified<T>
|
||||
>k : Extract<keyof T, string>
|
||||
>{ value: obj[k] } : { value: T[Extract<keyof T, string>]; }
|
||||
>value : T[Extract<keyof T, string>]
|
||||
>obj[k] : T[Extract<keyof T, string>]
|
||||
>obj : T
|
||||
>{ value: obj[k] } : { value: (T & object)[Extract<keyof T, string>]; }
|
||||
>value : (T & object)[Extract<keyof T, string>]
|
||||
>obj[k] : (T & object)[Extract<keyof T, string>]
|
||||
>obj : T & object
|
||||
>k : Extract<keyof T, string>
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -7,6 +7,20 @@ tests/cases/conformance/types/mapped/mappedTypes6.ts(37,5): error TS2322: Type '
|
||||
Type 'T[keyof T]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
Type 'T[string]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
Type 'T[string]' is not assignable to type 'T[P]'.
|
||||
Type 'string' is not assignable to type 'P'.
|
||||
'string' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
Type 'T[keyof T]' is not assignable to type 'T[P]'.
|
||||
Type 'keyof T' is not assignable to type 'P'.
|
||||
'keyof T' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
Type 'string | number | symbol' is not assignable to type 'P'.
|
||||
'string | number | symbol' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
Type 'string' is not assignable to type 'P'.
|
||||
'string' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
Type 'T[P]' is not assignable to type '{}'.
|
||||
Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
|
||||
Type 'T[string]' is not assignable to type '{}'.
|
||||
tests/cases/conformance/types/mapped/mappedTypes6.ts(38,5): error TS2322: Type 'T' is not assignable to type 'Denullified<T>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypes6.ts(39,5): error TS2322: Type 'Partial<T>' is not assignable to type 'Denullified<T>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypes6.ts(42,5): error TS2322: Type 'T' is not assignable to type 'Required<T>'.
|
||||
@@ -77,6 +91,20 @@ tests/cases/conformance/types/mapped/mappedTypes6.ts(120,4): error TS2540: Canno
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'NonNullable<T[P]>'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'T[P]'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'P'.
|
||||
!!! error TS2322: 'string' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[P]'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'P'.
|
||||
!!! error TS2322: 'keyof T' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'P'.
|
||||
!!! error TS2322: 'string | number | symbol' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'P'.
|
||||
!!! error TS2322: 'string' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.
|
||||
!!! error TS2322: Type 'T[P]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type '{}'.
|
||||
w = y; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'Denullified<T>'.
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts(25,11): error TS2430: Interface 'E1<T>' incorrectly extends interface 'Base'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'T' is not assignable to type '{ [key: string]: any; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts (1 errors) ====
|
||||
function f1<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: {};
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
function f2<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: { [x: string]: any };
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
function f3<T>(x: Partial<T>) {
|
||||
x = {};
|
||||
}
|
||||
|
||||
// Repro from #12900
|
||||
|
||||
interface Base {
|
||||
foo: { [key: string]: any };
|
||||
bar: any;
|
||||
baz: any;
|
||||
}
|
||||
|
||||
interface E1<T> extends Base {
|
||||
~~
|
||||
!!! error TS2430: Interface 'E1<T>' incorrectly extends interface 'Base'.
|
||||
!!! error TS2430: Types of property 'foo' are incompatible.
|
||||
!!! error TS2430: Type 'T' is not assignable to type '{ [key: string]: any; }'.
|
||||
!!! related TS2208 tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts:25:14: This type parameter probably needs an `extends object` constraint.
|
||||
foo: T;
|
||||
}
|
||||
|
||||
interface Something { name: string, value: string };
|
||||
interface E2 extends Base {
|
||||
foo: Partial<Something>; // or other mapped type
|
||||
}
|
||||
|
||||
interface E3<T> extends Base {
|
||||
foo: Partial<T>; // or other mapped type
|
||||
}
|
||||
|
||||
// Repro from #13747
|
||||
|
||||
class Form<T> {
|
||||
private values: {[P in keyof T]?: T[P]} = {}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ if (xUnknown == null) {
|
||||
|
||||
} else {
|
||||
xUnknown
|
||||
>xUnknown : unknown
|
||||
>xUnknown : {}
|
||||
}
|
||||
|
||||
if (xUnknown != null) {
|
||||
@@ -153,7 +153,7 @@ if (xUnknown != null) {
|
||||
>null : null
|
||||
|
||||
xUnknown;
|
||||
>xUnknown : unknown
|
||||
>xUnknown : {}
|
||||
|
||||
} else {
|
||||
xUnknown;
|
||||
|
||||
@@ -552,14 +552,14 @@ function multipleGenericFuse<X extends L | number, Y extends R | number>(xy: X |
|
||||
|
||||
case 'function': return [xy, 1];
|
||||
>'function' : "function"
|
||||
>[xy, 1] : [X, 1]
|
||||
>xy : X
|
||||
>[xy, 1] : [X & Function, 1]
|
||||
>xy : X & Function
|
||||
>1 : 1
|
||||
|
||||
case 'object': return [xy, 'two'];
|
||||
>'object' : "object"
|
||||
>[xy, 'two'] : [Y, string]
|
||||
>xy : Y
|
||||
>[xy, 'two'] : [Y & object, string]
|
||||
>xy : Y & object
|
||||
>'two' : "two"
|
||||
|
||||
case 'number': return [xy]
|
||||
@@ -843,7 +843,7 @@ function narrowingNarrows(x: {} | undefined) {
|
||||
case 'object': const _: {} = x; return;
|
||||
>'object' : "object"
|
||||
>_ : {}
|
||||
>x : {}
|
||||
>x : object
|
||||
|
||||
case 'string': assertString(x); return;
|
||||
>'string' : "string"
|
||||
@@ -1092,14 +1092,14 @@ function multipleGenericFuseWithBoth<X extends L | number, Y extends R | number>
|
||||
|
||||
case `function`: return [xy, 1];
|
||||
>`function` : "function"
|
||||
>[xy, 1] : [X, 1]
|
||||
>xy : X
|
||||
>[xy, 1] : [X & Function, 1]
|
||||
>xy : X & Function
|
||||
>1 : 1
|
||||
|
||||
case 'object': return [xy, 'two'];
|
||||
>'object' : "object"
|
||||
>[xy, 'two'] : [Y, string]
|
||||
>xy : Y
|
||||
>[xy, 'two'] : [Y & object, string]
|
||||
>xy : Y & object
|
||||
>'two' : "two"
|
||||
|
||||
case `number`: return [xy]
|
||||
|
||||
@@ -35,7 +35,7 @@ function foo(x: unknown, b: boolean) {
|
||||
>x : unknown
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
x.toString();
|
||||
@@ -51,7 +51,7 @@ function foo(x: unknown, b: boolean) {
|
||||
>x : unknown
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
x.toString();
|
||||
@@ -67,7 +67,7 @@ function foo(x: unknown, b: boolean) {
|
||||
>b : boolean
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
x.toString();
|
||||
@@ -85,7 +85,7 @@ function foo(x: unknown, b: boolean) {
|
||||
>b : true
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
x.toString();
|
||||
@@ -107,7 +107,7 @@ function foo(x: unknown, b: boolean) {
|
||||
>b : true
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
|
||||
x.toString();
|
||||
@@ -130,7 +130,7 @@ function f1(x: unknown): any {
|
||||
>x : unknown
|
||||
>typeof x === 'object' : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>x : {}
|
||||
>'object' : "object"
|
||||
>x.hasOwnProperty('x') : boolean
|
||||
>x.hasOwnProperty : (v: PropertyKey) => boolean
|
||||
|
||||
@@ -35,7 +35,7 @@ function f2<T>(x: (T & F) | T & string) {
|
||||
>"function" : "function"
|
||||
|
||||
x;
|
||||
>x : (T & F) | (T & string)
|
||||
>x : T & F
|
||||
}
|
||||
else {
|
||||
x;
|
||||
|
||||
@@ -180,7 +180,7 @@ declare function infiniteLoop1(): void;
|
||||
declare function infiniteLoop2(): never;
|
||||
declare function move1(direction: "up" | "down"): 1 | -1;
|
||||
declare function move2(direction: "up" | "down"): 1 | -1;
|
||||
declare function check<T>(x: T | undefined): T;
|
||||
declare function check<T>(x: T | undefined): NonNullable<T>;
|
||||
declare class C {
|
||||
void1(): void;
|
||||
void2(): void;
|
||||
|
||||
@@ -112,11 +112,11 @@ function move2(direction: "up" | "down") {
|
||||
}
|
||||
|
||||
function check<T>(x: T | undefined) {
|
||||
>check : <T>(x: T | undefined) => T
|
||||
>check : <T>(x: T | undefined) => NonNullable<T>
|
||||
>x : T | undefined
|
||||
|
||||
return x || error("Undefined value");
|
||||
>x || error("Undefined value") : T
|
||||
>x || error("Undefined value") : NonNullable<T>
|
||||
>x : T | undefined
|
||||
>error("Undefined value") : never
|
||||
>error : (message: string) => never
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/index.cts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
|
||||
/index.mts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
|
||||
|
||||
|
||||
==== /node_modules/@types/dedent/package.json (0 errors) ====
|
||||
{ "name": "@types/dedent", "version": "1.0.0", "main": "" }
|
||||
|
||||
==== /node_modules/@types/dedent2/package.json (0 errors) ====
|
||||
{ "name": "@types/dedent2", "version": "1.0.0", "main": "asdfasdfasdf" }
|
||||
|
||||
==== /node_modules/@types/dedent3/package.json (0 errors) ====
|
||||
{ "name": "@types/dedent3", "version": "1.0.0", "main": "asdfasdfasdf", "exports": null }
|
||||
|
||||
==== /node_modules/@types/dedent4/package.json (0 errors) ====
|
||||
{ "name": "@types/dedent4", "version": "1.0.0", "main": "asdfasdfasdf", "exports": "./asdfasdfasdf" }
|
||||
|
||||
==== /node_modules/@types/dedent/index.d.ts (0 errors) ====
|
||||
export {};
|
||||
|
||||
==== /node_modules/@types/dedent2/index.d.ts (0 errors) ====
|
||||
export {};
|
||||
|
||||
==== /node_modules/@types/dedent3/index.d.ts (0 errors) ====
|
||||
export {};
|
||||
|
||||
==== /node_modules/@types/dedent4/index.d.ts (0 errors) ====
|
||||
export {};
|
||||
|
||||
==== /index.mts (1 errors) ====
|
||||
import dedent from "dedent";
|
||||
import dedent2 from "dedent2";
|
||||
import dedent3 from "dedent3";
|
||||
import dedent4 from "dedent4"; // Error
|
||||
~~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
|
||||
|
||||
==== /index.cts (1 errors) ====
|
||||
import dedent from "dedent";
|
||||
import dedent2 from "dedent2";
|
||||
import dedent3 from "dedent3";
|
||||
import dedent4 from "dedent4"; // Error
|
||||
~~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//// [tests/cases/compiler/nodeNextImportModeImplicitIndexResolution2.ts] ////
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "@types/dedent", "version": "1.0.0", "main": "" }
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "@types/dedent2", "version": "1.0.0", "main": "asdfasdfasdf" }
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "@types/dedent3", "version": "1.0.0", "main": "asdfasdfasdf", "exports": null }
|
||||
|
||||
//// [package.json]
|
||||
{ "name": "@types/dedent4", "version": "1.0.0", "main": "asdfasdfasdf", "exports": "./asdfasdfasdf" }
|
||||
|
||||
//// [index.d.ts]
|
||||
export {};
|
||||
|
||||
//// [index.d.ts]
|
||||
export {};
|
||||
|
||||
//// [index.d.ts]
|
||||
export {};
|
||||
|
||||
//// [index.d.ts]
|
||||
export {};
|
||||
|
||||
//// [index.mts]
|
||||
import dedent from "dedent";
|
||||
import dedent2 from "dedent2";
|
||||
import dedent3 from "dedent3";
|
||||
import dedent4 from "dedent4"; // Error
|
||||
|
||||
//// [index.cts]
|
||||
import dedent from "dedent";
|
||||
import dedent2 from "dedent2";
|
||||
import dedent3 from "dedent3";
|
||||
import dedent4 from "dedent4"; // Error
|
||||
|
||||
|
||||
//// [index.mjs]
|
||||
export {};
|
||||
//// [index.cjs]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
@@ -0,0 +1,38 @@
|
||||
=== /node_modules/@types/dedent/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent2/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent3/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent4/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /index.mts ===
|
||||
import dedent from "dedent";
|
||||
>dedent : Symbol(dedent, Decl(index.mts, 0, 6))
|
||||
|
||||
import dedent2 from "dedent2";
|
||||
>dedent2 : Symbol(dedent2, Decl(index.mts, 1, 6))
|
||||
|
||||
import dedent3 from "dedent3";
|
||||
>dedent3 : Symbol(dedent3, Decl(index.mts, 2, 6))
|
||||
|
||||
import dedent4 from "dedent4"; // Error
|
||||
>dedent4 : Symbol(dedent4, Decl(index.mts, 3, 6))
|
||||
|
||||
=== /index.cts ===
|
||||
import dedent from "dedent";
|
||||
>dedent : Symbol(dedent, Decl(index.cts, 0, 6))
|
||||
|
||||
import dedent2 from "dedent2";
|
||||
>dedent2 : Symbol(dedent2, Decl(index.cts, 1, 6))
|
||||
|
||||
import dedent3 from "dedent3";
|
||||
>dedent3 : Symbol(dedent3, Decl(index.cts, 2, 6))
|
||||
|
||||
import dedent4 from "dedent4"; // Error
|
||||
>dedent4 : Symbol(dedent4, Decl(index.cts, 3, 6))
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
=== /node_modules/@types/dedent/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent2/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent3/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /node_modules/@types/dedent4/index.d.ts ===
|
||||
export {};
|
||||
No type information for this code.
|
||||
No type information for this code.=== /index.mts ===
|
||||
import dedent from "dedent";
|
||||
>dedent : typeof dedent
|
||||
|
||||
import dedent2 from "dedent2";
|
||||
>dedent2 : typeof dedent2
|
||||
|
||||
import dedent3 from "dedent3";
|
||||
>dedent3 : typeof dedent3
|
||||
|
||||
import dedent4 from "dedent4"; // Error
|
||||
>dedent4 : any
|
||||
|
||||
=== /index.cts ===
|
||||
import dedent from "dedent";
|
||||
>dedent : typeof dedent
|
||||
|
||||
import dedent2 from "dedent2";
|
||||
>dedent2 : typeof dedent2
|
||||
|
||||
import dedent3 from "dedent3";
|
||||
>dedent3 : typeof dedent3
|
||||
|
||||
import dedent4 from "dedent4"; // Error
|
||||
>dedent4 : any
|
||||
|
||||
@@ -25,7 +25,7 @@ function fn<T extends string | undefined, U extends string>(one: T, two: U) {
|
||||
foo(two!);
|
||||
>foo(two!) : void
|
||||
>foo : (p: string) => void
|
||||
>two! : NonNullable<U>
|
||||
>two! : U
|
||||
>two : U
|
||||
|
||||
foo(three!); // this line is the important one
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//// [nonNullableTypes1.ts]
|
||||
function f1<T>(x: T) {
|
||||
let y = x || "hello"; // NonNullable<T> | string
|
||||
}
|
||||
|
||||
function error(): never {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function f2<T>(x: T) { // NonNullable<T>
|
||||
return x || error();
|
||||
}
|
||||
|
||||
function f3(x: unknown) {
|
||||
let y = x!; // {}
|
||||
}
|
||||
|
||||
function f4<T extends { x: string } | undefined>(obj: T) {
|
||||
if (obj?.x === "hello") {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
if (obj?.x) {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
if (typeof obj?.x === "string") {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
x = "hello";
|
||||
foo() {
|
||||
let zz = this?.x; // string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [nonNullableTypes1.js]
|
||||
"use strict";
|
||||
function f1(x) {
|
||||
var y = x || "hello"; // NonNullable<T> | string
|
||||
}
|
||||
function error() {
|
||||
throw new Error();
|
||||
}
|
||||
function f2(x) {
|
||||
return x || error();
|
||||
}
|
||||
function f3(x) {
|
||||
var y = x; // {}
|
||||
}
|
||||
function f4(obj) {
|
||||
if ((obj === null || obj === void 0 ? void 0 : obj.x) === "hello") {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
if (obj === null || obj === void 0 ? void 0 : obj.x) {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
if (typeof (obj === null || obj === void 0 ? void 0 : obj.x) === "string") {
|
||||
obj; // NonNullable<T>
|
||||
}
|
||||
}
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
this.x = "hello";
|
||||
}
|
||||
A.prototype.foo = function () {
|
||||
var zz = this === null || this === void 0 ? void 0 : this.x; // string
|
||||
};
|
||||
return A;
|
||||
}());
|
||||
|
||||
|
||||
//// [nonNullableTypes1.d.ts]
|
||||
declare function f1<T>(x: T): void;
|
||||
declare function error(): never;
|
||||
declare function f2<T>(x: T): NonNullable<T>;
|
||||
declare function f3(x: unknown): void;
|
||||
declare function f4<T extends {
|
||||
x: string;
|
||||
} | undefined>(obj: T): void;
|
||||
declare class A {
|
||||
x: string;
|
||||
foo(): void;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
=== tests/cases/compiler/nonNullableTypes1.ts ===
|
||||
function f1<T>(x: T) {
|
||||
>f1 : Symbol(f1, Decl(nonNullableTypes1.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 0, 12))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 0, 15))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 0, 12))
|
||||
|
||||
let y = x || "hello"; // NonNullable<T> | string
|
||||
>y : Symbol(y, Decl(nonNullableTypes1.ts, 1, 7))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 0, 15))
|
||||
}
|
||||
|
||||
function error(): never {
|
||||
>error : Symbol(error, Decl(nonNullableTypes1.ts, 2, 1))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
function f2<T>(x: T) { // NonNullable<T>
|
||||
>f2 : Symbol(f2, Decl(nonNullableTypes1.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 8, 12))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 8, 15))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 8, 12))
|
||||
|
||||
return x || error();
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 8, 15))
|
||||
>error : Symbol(error, Decl(nonNullableTypes1.ts, 2, 1))
|
||||
}
|
||||
|
||||
function f3(x: unknown) {
|
||||
>f3 : Symbol(f3, Decl(nonNullableTypes1.ts, 10, 1))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 12, 12))
|
||||
|
||||
let y = x!; // {}
|
||||
>y : Symbol(y, Decl(nonNullableTypes1.ts, 13, 7))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 12, 12))
|
||||
}
|
||||
|
||||
function f4<T extends { x: string } | undefined>(obj: T) {
|
||||
>f4 : Symbol(f4, Decl(nonNullableTypes1.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 16, 12))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
>T : Symbol(T, Decl(nonNullableTypes1.ts, 16, 12))
|
||||
|
||||
if (obj?.x === "hello") {
|
||||
>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
}
|
||||
if (obj?.x) {
|
||||
>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
}
|
||||
if (typeof obj?.x === "string") {
|
||||
>obj?.x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
>x : Symbol(x, Decl(nonNullableTypes1.ts, 16, 23))
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : Symbol(obj, Decl(nonNullableTypes1.ts, 16, 49))
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
>A : Symbol(A, Decl(nonNullableTypes1.ts, 26, 1))
|
||||
|
||||
x = "hello";
|
||||
>x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9))
|
||||
|
||||
foo() {
|
||||
>foo : Symbol(A.foo, Decl(nonNullableTypes1.ts, 29, 16))
|
||||
|
||||
let zz = this?.x; // string
|
||||
>zz : Symbol(zz, Decl(nonNullableTypes1.ts, 31, 11))
|
||||
>this?.x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9))
|
||||
>this : Symbol(A, Decl(nonNullableTypes1.ts, 26, 1))
|
||||
>x : Symbol(A.x, Decl(nonNullableTypes1.ts, 28, 9))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
=== tests/cases/compiler/nonNullableTypes1.ts ===
|
||||
function f1<T>(x: T) {
|
||||
>f1 : <T>(x: T) => void
|
||||
>x : T
|
||||
|
||||
let y = x || "hello"; // NonNullable<T> | string
|
||||
>y : string | NonNullable<T>
|
||||
>x || "hello" : "hello" | NonNullable<T>
|
||||
>x : T
|
||||
>"hello" : "hello"
|
||||
}
|
||||
|
||||
function error(): never {
|
||||
>error : () => never
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
function f2<T>(x: T) { // NonNullable<T>
|
||||
>f2 : <T>(x: T) => NonNullable<T>
|
||||
>x : T
|
||||
|
||||
return x || error();
|
||||
>x || error() : NonNullable<T>
|
||||
>x : T
|
||||
>error() : never
|
||||
>error : () => never
|
||||
}
|
||||
|
||||
function f3(x: unknown) {
|
||||
>f3 : (x: unknown) => void
|
||||
>x : unknown
|
||||
|
||||
let y = x!; // {}
|
||||
>y : {}
|
||||
>x! : {}
|
||||
>x : unknown
|
||||
}
|
||||
|
||||
function f4<T extends { x: string } | undefined>(obj: T) {
|
||||
>f4 : <T extends { x: string; } | undefined>(obj: T) => void
|
||||
>x : string
|
||||
>obj : T
|
||||
|
||||
if (obj?.x === "hello") {
|
||||
>obj?.x === "hello" : boolean
|
||||
>obj?.x : string | undefined
|
||||
>obj : { x: string; } | undefined
|
||||
>x : string | undefined
|
||||
>"hello" : "hello"
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : NonNullable<T>
|
||||
}
|
||||
if (obj?.x) {
|
||||
>obj?.x : string | undefined
|
||||
>obj : { x: string; } | undefined
|
||||
>x : string | undefined
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : NonNullable<T>
|
||||
}
|
||||
if (typeof obj?.x === "string") {
|
||||
>typeof obj?.x === "string" : boolean
|
||||
>typeof obj?.x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>obj?.x : string | undefined
|
||||
>obj : { x: string; } | undefined
|
||||
>x : string | undefined
|
||||
>"string" : "string"
|
||||
|
||||
obj; // NonNullable<T>
|
||||
>obj : NonNullable<T>
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
x = "hello";
|
||||
>x : string
|
||||
>"hello" : "hello"
|
||||
|
||||
foo() {
|
||||
>foo : () => void
|
||||
|
||||
let zz = this?.x; // string
|
||||
>zz : string
|
||||
>this?.x : string
|
||||
>this : this
|
||||
>x : string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(3,5): error TS2322: Type 'number' is not assignable to type 'object & {}'.
|
||||
Type 'number' is not assignable to type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(3,5): error TS2322: Type 'number' is not assignable to type 'object'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(4,1): error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38): error TS2322: Type '{ bar: string; }' is not assignable to type 'object & { err: string; }'.
|
||||
Object literal may only specify known properties, and 'bar' does not exist in type 'object & { err: string; }'.
|
||||
@@ -13,8 +12,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38
|
||||
var b: object | string = ""; // ok
|
||||
var c: object & {} = 123; // error
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'object & {}'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'object'.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'object'.
|
||||
a = b; // error
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
|
||||
@@ -8,7 +8,7 @@ var b: object | string = ""; // ok
|
||||
>"" : ""
|
||||
|
||||
var c: object & {} = 123; // error
|
||||
>c : object & {}
|
||||
>c : object
|
||||
>123 : 123
|
||||
|
||||
a = b; // error
|
||||
@@ -22,7 +22,7 @@ b = a; // ok
|
||||
>a : never
|
||||
|
||||
const foo: object & {} = {bar: 'bar'}; // ok
|
||||
>foo : object & {}
|
||||
>foo : object
|
||||
>{bar: 'bar'} : { bar: string; }
|
||||
>bar : string
|
||||
>'bar' : "bar"
|
||||
|
||||
@@ -75,8 +75,8 @@ const aa6 = a6 ?? 'whatever'
|
||||
>'whatever' : "whatever"
|
||||
|
||||
const aa7 = a7 ?? 'whatever'
|
||||
>aa7 : unknown
|
||||
>a7 ?? 'whatever' : unknown
|
||||
>aa7 : {}
|
||||
>a7 ?? 'whatever' : {}
|
||||
>a7 : unknown
|
||||
>'whatever' : "whatever"
|
||||
|
||||
|
||||
@@ -75,8 +75,8 @@ const aa6 = a6 ?? 'whatever'
|
||||
>'whatever' : "whatever"
|
||||
|
||||
const aa7 = a7 ?? 'whatever'
|
||||
>aa7 : unknown
|
||||
>a7 ?? 'whatever' : unknown
|
||||
>aa7 : {}
|
||||
>a7 ?? 'whatever' : {}
|
||||
>a7 : unknown
|
||||
>'whatever' : "whatever"
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
tests/cases/compiler/omittedExpressionForOfLoop.ts(1,19): error TS2304: Cannot find name 'doesNotExist'.
|
||||
tests/cases/compiler/omittedExpressionForOfLoop.ts(4,19): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/compiler/omittedExpressionForOfLoop.ts(7,12): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
|
||||
tests/cases/compiler/omittedExpressionForOfLoop.ts(10,12): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
|
||||
|
||||
|
||||
==== tests/cases/compiler/omittedExpressionForOfLoop.ts (4 errors) ====
|
||||
for (const [,] of doesNotExist) {
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'doesNotExist'.
|
||||
}
|
||||
|
||||
for (const [,] of undefined) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
|
||||
for (const [,] of []) {
|
||||
~~~
|
||||
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
|
||||
}
|
||||
|
||||
for (const [] of []) {
|
||||
~~
|
||||
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//// [omittedExpressionForOfLoop.ts]
|
||||
for (const [,] of doesNotExist) {
|
||||
}
|
||||
|
||||
for (const [,] of undefined) {
|
||||
}
|
||||
|
||||
for (const [,] of []) {
|
||||
}
|
||||
|
||||
for (const [] of []) {
|
||||
}
|
||||
|
||||
//// [omittedExpressionForOfLoop.js]
|
||||
"use strict";
|
||||
for (const [,] of doesNotExist) {
|
||||
}
|
||||
for (const [,] of undefined) {
|
||||
}
|
||||
for (const [,] of []) {
|
||||
}
|
||||
for (const [] of []) {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/omittedExpressionForOfLoop.ts ===
|
||||
for (const [,] of doesNotExist) {
|
||||
}
|
||||
|
||||
for (const [,] of undefined) {
|
||||
>undefined : Symbol(undefined)
|
||||
}
|
||||
|
||||
for (const [,] of []) {
|
||||
}
|
||||
|
||||
for (const [] of []) {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/omittedExpressionForOfLoop.ts ===
|
||||
for (const [,] of doesNotExist) {
|
||||
> : undefined
|
||||
>doesNotExist : any
|
||||
}
|
||||
|
||||
for (const [,] of undefined) {
|
||||
> : undefined
|
||||
>undefined : undefined
|
||||
}
|
||||
|
||||
for (const [,] of []) {
|
||||
> : undefined
|
||||
>[] : never[]
|
||||
}
|
||||
|
||||
for (const [] of []) {
|
||||
>[] : never[]
|
||||
}
|
||||
@@ -28,10 +28,10 @@ class A {
|
||||
|
||||
this?.getA().#b; // Error
|
||||
>this?.getA().#b : A | undefined
|
||||
>this?.getA() : A | undefined
|
||||
>this?.getA : (() => A) | undefined
|
||||
>this?.getA() : A
|
||||
>this?.getA : () => A
|
||||
>this : this
|
||||
>getA : (() => A) | undefined
|
||||
>getA : () => A
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ const arrayOfTypes = [PropTypes.string, PropTypes.bool, PropTypes.shape({
|
||||
// TS checking
|
||||
const propTypes: PropTypesMap = {
|
||||
>propTypes : PropTypes.ValidationMap<Props>
|
||||
>{ any: PropTypes.any, array: PropTypes.array.isRequired, bool: PropTypes.bool.isRequired, shape: PropTypes.shape(innerProps).isRequired, oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,} : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }
|
||||
>{ any: PropTypes.any, array: PropTypes.array.isRequired, bool: PropTypes.bool.isRequired, shape: PropTypes.shape(innerProps).isRequired, oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,} : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }
|
||||
|
||||
any: PropTypes.any,
|
||||
>any : PropTypes.Requireable<any>
|
||||
@@ -204,31 +204,31 @@ const propTypes: PropTypesMap = {
|
||||
>isRequired : PropTypes.Validator<boolean>
|
||||
|
||||
shape: PropTypes.shape(innerProps).isRequired,
|
||||
>shape : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>PropTypes.shape(innerProps).isRequired : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>shape : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
>PropTypes.shape(innerProps).isRequired : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
>PropTypes.shape(innerProps) : PropTypes.Requireable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>PropTypes.shape : <P extends PropTypes.ValidationMap<any>>(type: P) => PropTypes.Requireable<PropTypes.InferProps<P>>
|
||||
>PropTypes : typeof PropTypes
|
||||
>shape : <P extends PropTypes.ValidationMap<any>>(type: P) => PropTypes.Requireable<PropTypes.InferProps<P>>
|
||||
>innerProps : { foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }
|
||||
>isRequired : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>isRequired : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
|
||||
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
||||
>oneOfType : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>PropTypes.oneOfType(arrayOfTypes) : PropTypes.Requireable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>oneOfType : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
>PropTypes.oneOfType(arrayOfTypes) : PropTypes.Requireable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>
|
||||
>PropTypes.oneOfType : <T extends PropTypes.Validator<any>>(types: T[]) => PropTypes.Requireable<NonNullable<PropTypes.InferType<T>>>
|
||||
>PropTypes : typeof PropTypes
|
||||
>oneOfType : <T extends PropTypes.Validator<any>>(types: T[]) => PropTypes.Requireable<NonNullable<PropTypes.InferType<T>>>
|
||||
>arrayOfTypes : (PropTypes.Requireable<boolean> | PropTypes.Requireable<string> | PropTypes.Requireable<PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>)[]
|
||||
>isRequired : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>isRequired : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
|
||||
};
|
||||
|
||||
// JS checking
|
||||
const propTypesWithoutAnnotation = {
|
||||
>propTypesWithoutAnnotation : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }
|
||||
>{ any: PropTypes.any, array: PropTypes.array.isRequired, bool: PropTypes.bool.isRequired, shape: PropTypes.shape(innerProps).isRequired, oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,} : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }
|
||||
>propTypesWithoutAnnotation : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }
|
||||
>{ any: PropTypes.any, array: PropTypes.array.isRequired, bool: PropTypes.bool.isRequired, shape: PropTypes.shape(innerProps).isRequired, oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,} : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }
|
||||
|
||||
any: PropTypes.any,
|
||||
>any : PropTypes.Requireable<any>
|
||||
@@ -253,24 +253,24 @@ const propTypesWithoutAnnotation = {
|
||||
>isRequired : PropTypes.Validator<boolean>
|
||||
|
||||
shape: PropTypes.shape(innerProps).isRequired,
|
||||
>shape : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>PropTypes.shape(innerProps).isRequired : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>shape : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
>PropTypes.shape(innerProps).isRequired : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
>PropTypes.shape(innerProps) : PropTypes.Requireable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>PropTypes.shape : <P extends PropTypes.ValidationMap<any>>(type: P) => PropTypes.Requireable<PropTypes.InferProps<P>>
|
||||
>PropTypes : typeof PropTypes
|
||||
>shape : <P extends PropTypes.ValidationMap<any>>(type: P) => PropTypes.Requireable<PropTypes.InferProps<P>>
|
||||
>innerProps : { foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }
|
||||
>isRequired : PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>
|
||||
>isRequired : PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>
|
||||
|
||||
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
||||
>oneOfType : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>PropTypes.oneOfType(arrayOfTypes) : PropTypes.Requireable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>oneOfType : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
>PropTypes.oneOfType(arrayOfTypes) : PropTypes.Requireable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>
|
||||
>PropTypes.oneOfType : <T extends PropTypes.Validator<any>>(types: T[]) => PropTypes.Requireable<NonNullable<PropTypes.InferType<T>>>
|
||||
>PropTypes : typeof PropTypes
|
||||
>oneOfType : <T extends PropTypes.Validator<any>>(types: T[]) => PropTypes.Requireable<NonNullable<PropTypes.InferType<T>>>
|
||||
>arrayOfTypes : (PropTypes.Requireable<boolean> | PropTypes.Requireable<string> | PropTypes.Requireable<PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>)[]
|
||||
>isRequired : PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>
|
||||
>isRequired : PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>
|
||||
|
||||
};
|
||||
|
||||
@@ -280,9 +280,9 @@ type ExtractedProps = PropTypes.InferProps<typeof propTypes>;
|
||||
>propTypes : PropTypes.ValidationMap<Props>
|
||||
|
||||
type ExtractedPropsWithoutAnnotation = PropTypes.InferProps<typeof propTypesWithoutAnnotation>;
|
||||
>ExtractedPropsWithoutAnnotation : PropTypes.InferPropsInner<Pick<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }, PropTypes.RequiredKeys<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }>>> & Partial<PropTypes.InferPropsInner<Pick<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }, "any">>>
|
||||
>ExtractedPropsWithoutAnnotation : PropTypes.InferPropsInner<Pick<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }, PropTypes.RequiredKeys<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }>>> & Partial<PropTypes.InferPropsInner<Pick<{ any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }, "any">>>
|
||||
>PropTypes : any
|
||||
>propTypesWithoutAnnotation : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>; oneOfType: PropTypes.Validator<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>; }
|
||||
>propTypesWithoutAnnotation : { any: PropTypes.Requireable<any>; array: PropTypes.Validator<any[]>; bool: PropTypes.Validator<boolean>; shape: PropTypes.Validator<NonNullable<PropTypes.InferProps<{ foo: PropTypes.Validator<string>; bar: PropTypes.Requireable<boolean>; baz: PropTypes.Requireable<any>; }>>>; oneOfType: PropTypes.Validator<NonNullable<NonNullable<string | boolean | PropTypes.InferProps<{ foo: PropTypes.Requireable<string>; bar: PropTypes.Validator<number>; }>>>>; }
|
||||
|
||||
type ExtractPropsMatch = ExtractedProps extends ExtractedPropsWithoutAnnotation ? true : false;
|
||||
>ExtractPropsMatch : true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
tests/cases/compiler/recursiveTupleTypeInference.ts(23,5): error TS2345: Argument of type '{ b: A; }' is not assignable to parameter of type 'G<{ b: unknown; }>'.
|
||||
Types of property 'b' are incompatible.
|
||||
Type 'A' is not assignable to type '[[[[[[[[[[[[any, "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"]'.
|
||||
Type 'string' is not assignable to type '[[[[[[[[[[[[any, "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"]'.
|
||||
Type 'A' is not assignable to type '[never, "null"]'.
|
||||
Type 'string' is not assignable to type '[never, "null"]'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/recursiveTupleTypeInference.ts (1 errors) ====
|
||||
@@ -31,6 +31,6 @@ tests/cases/compiler/recursiveTupleTypeInference.ts(23,5): error TS2345: Argumen
|
||||
~~
|
||||
!!! error TS2345: Argument of type '{ b: A; }' is not assignable to parameter of type 'G<{ b: unknown; }>'.
|
||||
!!! error TS2345: Types of property 'b' are incompatible.
|
||||
!!! error TS2345: Type 'A' is not assignable to type '[[[[[[[[[[[[any, "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"]'.
|
||||
!!! error TS2345: Type 'string' is not assignable to type '[[[[[[[[[[[[any, "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"], "null"]'.
|
||||
!!! error TS2345: Type 'A' is not assignable to type '[never, "null"]'.
|
||||
!!! error TS2345: Type 'string' is not assignable to type '[never, "null"]'.
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ function JustConditional<T>(): ConditionalType<T> {
|
||||
>JustConditional : <T>() => ConditionalType<T>
|
||||
|
||||
return ConditionalOrUndefined<T>()!; // shouldn't error
|
||||
>ConditionalOrUndefined<T>()! : NonNullable<ConditionalType<T>>
|
||||
>ConditionalOrUndefined<T>()! : ConditionalType<T>
|
||||
>ConditionalOrUndefined<T>() : ConditionalType<T> | undefined
|
||||
>ConditionalOrUndefined : <T>() => ConditionalType<T> | undefined
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ declare function f5<S, T extends undefined>(a: S | T): S | T;
|
||||
declare function f6<T extends object | undefined>(a: T): T;
|
||||
declare function g1<T extends {}, A extends {
|
||||
z: (T | undefined) & T;
|
||||
}>(a: A): (T | undefined) & T;
|
||||
}>(a: A): T | (undefined & T);
|
||||
interface DatafulFoo<T> {
|
||||
data: T;
|
||||
}
|
||||
|
||||
@@ -56,19 +56,19 @@ function f6<T extends object | undefined>(a: T) {
|
||||
// Repro from #46976
|
||||
|
||||
function g1<T extends {}, A extends { z: (T | undefined) & T }>(a: A) {
|
||||
>g1 : <T extends {}, A extends { z: (T | undefined) & T; }>(a: A) => (T | undefined) & T
|
||||
>z : (T | undefined) & T
|
||||
>g1 : <T extends {}, A extends { z: (T | undefined) & T; }>(a: A) => T | (undefined & T)
|
||||
>z : T | (undefined & T)
|
||||
>a : A
|
||||
|
||||
const { z } = a;
|
||||
>z : (T | undefined) & T
|
||||
>z : T | (undefined & T)
|
||||
>a : A
|
||||
|
||||
return {
|
||||
>{ ...z } : (T | undefined) & T
|
||||
>{ ...z } : T | (undefined & T)
|
||||
|
||||
...z
|
||||
>z : (T | undefined) & T
|
||||
>z : T | (undefined & T)
|
||||
|
||||
};
|
||||
}
|
||||
@@ -98,9 +98,9 @@ class Foo<T extends string> {
|
||||
this.data.toLocaleLowerCase();
|
||||
>this.data.toLocaleLowerCase() : string
|
||||
>this.data.toLocaleLowerCase : (locales?: string | string[] | undefined) => string
|
||||
>this.data : (T | undefined) & T
|
||||
>this.data : T | (undefined & T)
|
||||
>this : this & DatafulFoo<T>
|
||||
>data : (T | undefined) & T
|
||||
>data : T | (undefined & T)
|
||||
>toLocaleLowerCase : (locales?: string | string[] | undefined) => string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ error TS2318: Cannot find global type 'Number'.
|
||||
error TS2318: Cannot find global type 'Object'.
|
||||
error TS2318: Cannot find global type 'RegExp'.
|
||||
error TS2318: Cannot find global type 'String'.
|
||||
tests/cases/compiler/strictNullNotNullIndexTypeNoLib.ts(10,28): error TS2339: Property 'name' does not exist on type 'T["params"]'.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Array'.
|
||||
@@ -17,7 +16,7 @@ tests/cases/compiler/strictNullNotNullIndexTypeNoLib.ts(10,28): error TS2339: Pr
|
||||
!!! error TS2318: Cannot find global type 'Object'.
|
||||
!!! error TS2318: Cannot find global type 'RegExp'.
|
||||
!!! error TS2318: Cannot find global type 'String'.
|
||||
==== tests/cases/compiler/strictNullNotNullIndexTypeNoLib.ts (1 errors) ====
|
||||
==== tests/cases/compiler/strictNullNotNullIndexTypeNoLib.ts (0 errors) ====
|
||||
type Readonly<T> = {readonly [K in keyof T]: T[K]}
|
||||
interface A {
|
||||
params?: { name: string; };
|
||||
@@ -28,8 +27,6 @@ tests/cases/compiler/strictNullNotNullIndexTypeNoLib.ts(10,28): error TS2339: Pr
|
||||
|
||||
m() {
|
||||
this.attrs.params!.name;
|
||||
~~~~
|
||||
!!! error TS2339: Property 'name' does not exist on type 'T["params"]'.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,13 @@ class Test<T extends A> {
|
||||
>m : Symbol(Test.m, Decl(strictNullNotNullIndexTypeNoLib.ts, 6, 23))
|
||||
|
||||
this.attrs.params!.name;
|
||||
>this.attrs.params!.name : Symbol(name, Decl(strictNullNotNullIndexTypeNoLib.ts, 2, 14))
|
||||
>this.attrs.params : Symbol(params, Decl(strictNullNotNullIndexTypeNoLib.ts, 1, 13))
|
||||
>this.attrs : Symbol(Test.attrs, Decl(strictNullNotNullIndexTypeNoLib.ts, 5, 25))
|
||||
>this : Symbol(Test, Decl(strictNullNotNullIndexTypeNoLib.ts, 3, 1))
|
||||
>attrs : Symbol(Test.attrs, Decl(strictNullNotNullIndexTypeNoLib.ts, 5, 25))
|
||||
>params : Symbol(params, Decl(strictNullNotNullIndexTypeNoLib.ts, 1, 13))
|
||||
>name : Symbol(name, Decl(strictNullNotNullIndexTypeNoLib.ts, 2, 14))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@ class Test<T extends A> {
|
||||
>m : () => void
|
||||
|
||||
this.attrs.params!.name;
|
||||
>this.attrs.params!.name : any
|
||||
>this.attrs.params! : T["params"]
|
||||
>this.attrs.params!.name : string
|
||||
>this.attrs.params! : T["params"] & {}
|
||||
>this.attrs.params : T["params"] | undefined
|
||||
>this.attrs : Readonly<T>
|
||||
>this : this
|
||||
>attrs : Readonly<T>
|
||||
>params : T["params"] | undefined
|
||||
>name : any
|
||||
>name : string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ class Test2<T extends A> {
|
||||
>attrs : Readonly<T>
|
||||
|
||||
m() {
|
||||
>m : () => T["params"]
|
||||
>m : () => T["params"] & {}
|
||||
|
||||
return this.attrs.params!; // Return type should maintain relationship with `T` after being not-null-asserted, ideally
|
||||
>this.attrs.params! : T["params"]
|
||||
>this.attrs.params! : T["params"] & {}
|
||||
>this.attrs.params : T["params"] | undefined
|
||||
>this.attrs : Readonly<T>
|
||||
>this : this
|
||||
|
||||
@@ -653,7 +653,7 @@ function expectNotUndefined<T>(value: Undefinable<T>): T {
|
||||
>'value is undefined' : "value is undefined"
|
||||
}
|
||||
return value;
|
||||
>value : T
|
||||
>value : T & ({} | null)
|
||||
}
|
||||
|
||||
interface Bar {
|
||||
|
||||
@@ -54,7 +54,7 @@ type E = `${A & {}}`;
|
||||
>E : "a"
|
||||
|
||||
type MixE = E & {}
|
||||
>MixE : "a" & {}
|
||||
>MixE : "a"
|
||||
|
||||
type OriginE = `${MixE}`
|
||||
>OriginE : "a"
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes4.ts(285,12): error TS2345: Argument of type '2' is not assignable to parameter of type '0 | 1'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes4.ts(289,12): error TS2345: Argument of type '2' is not assignable to parameter of type '0 | 1'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/literal/templateLiteralTypes4.ts (2 errors) ====
|
||||
// infer from number
|
||||
type TNumber0 = "100" extends `${infer N extends number}` ? N : never; // 100
|
||||
type TNumber1 = "-100" extends `${infer N extends number}` ? N : never; // -100
|
||||
type TNumber2 = "1.1" extends `${infer N extends number}` ? N : never; // 1.1
|
||||
type TNumber3 = "8e-11" extends `${infer N extends number}` ? N : never; // 8e-11 (0.00000000008)
|
||||
type TNumber4 = "0x10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber5 = "0o10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber6 = "0b10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber7 = "10e2" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber8 = "abcd" extends `${infer N extends number}` ? N : never; // never
|
||||
|
||||
// infer from bigint
|
||||
type TBigInt0 = "100" extends `${infer N extends bigint}` ? N : never; // 100n
|
||||
type TBigInt1 = "-100" extends `${infer N extends bigint}` ? N : never; // -100n
|
||||
type TBigInt2 = "0x10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt3 = "0o10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt4 = "0b10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt5 = "1.1" extends `${infer N extends bigint}` ? N : never; // never
|
||||
type TBigInt6 = "10e2" extends `${infer N extends bigint}` ? N : never; // never
|
||||
type TBigInt7 = "abcd" extends `${infer N extends bigint}` ? N : never; // never
|
||||
|
||||
// infer from boolean
|
||||
type TBoolean0 = "true" extends `${infer T extends boolean}` ? T : never; // true
|
||||
type TBoolean1 = "false" extends `${infer T extends boolean}` ? T : never; // false
|
||||
type TBoolean2 = "abcd" extends `${infer T extends boolean}` ? T : never; // never
|
||||
|
||||
// infer from null
|
||||
type TNull0 = "null" extends `${infer T extends null}` ? T : never; // null
|
||||
type TNull1 = "abcd" extends `${infer T extends null}` ? T : never; // never
|
||||
|
||||
// infer from undefined
|
||||
type TUndefined0 = "undefined" extends `${infer T extends undefined}` ? T : never; // undefined
|
||||
type TUndefined1 = "abcd" extends `${infer T extends undefined}` ? T : never; // never
|
||||
|
||||
// infer from literal enums
|
||||
const enum StringLiteralEnum { Zero = "0", True = "true", False = "false", Undefined = "undefined", Null = "null" }
|
||||
type TStringLiteralEnum0 = "0" extends `${infer T extends StringLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
const enum NumberLiteralEnum { Zero, One }
|
||||
type TNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum}` ? T : never; // NumberLiteralEnum.Zero
|
||||
|
||||
// infer from non-literal enums
|
||||
const enum NonLiteralEnum { Zero = NumberLiteralEnum.Zero, One = NumberLiteralEnum.One }
|
||||
type TNonLiteralEnum0 = "0" extends `${infer T extends NonLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// infer using priority:
|
||||
// string > template-literal > (string-literal | string-literal-enum) >
|
||||
// number > enum > (number-literal | number-literal-enum) >
|
||||
// bigint > bigint-literal >
|
||||
// boolean > (boolean-literal | undefined | null)
|
||||
|
||||
// #region string
|
||||
// string > string-literal-enum
|
||||
type PString00 = "0" extends `${infer T extends string | StringLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > number
|
||||
type PString01 = "0" extends `${infer T extends string | number}` ? T : never; // "0"
|
||||
|
||||
// string > enum
|
||||
type PString02 = "0" extends `${infer T extends string | NonLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > (number-literal | number-literal-enum)
|
||||
type PString03 = "0" extends `${infer T extends string | 0}` ? T : never; // "0"
|
||||
type PString04 = "0" extends `${infer T extends string | NumberLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > bigint
|
||||
type PString05 = "0" extends `${infer T extends string | bigint}` ? T : never; // "0"
|
||||
|
||||
// string > bigint-literal
|
||||
type PString06 = "0" extends `${infer T extends string | 0n}` ? T : never; // "0"
|
||||
|
||||
// string > boolean
|
||||
type PString07 = "true" extends `${infer T extends string | boolean}` ? T : never; // "true"
|
||||
type PString08 = "false" extends `${infer T extends string | boolean}` ? T : never; // "false"
|
||||
|
||||
// string > (boolean-literal | undefined | null)
|
||||
type PString09 = "true" extends `${infer T extends string | true}` ? T : never; // "true"
|
||||
type PString10 = "false" extends `${infer T extends string | false}` ? T : never; // "false"
|
||||
type PString11 = "undefined" extends `${infer T extends string | undefined}` ? T : never; // "undefined"
|
||||
type PString12 = "null" extends `${infer T extends string | null}` ? T : never; // "null"
|
||||
// #endregion string
|
||||
|
||||
// #region template-literal
|
||||
// template-literal > number
|
||||
type PTemplate00 = "10" extends `${infer T extends `1${string}` | number}` ? T : never; // "10"
|
||||
|
||||
// template-literal > enum
|
||||
type PTemplate01 = "10" extends `${infer T extends `1${string}` | NonLiteralEnum}` ? T : never; // "10"
|
||||
|
||||
// template-literal > (number-literal | number-literal-enum)
|
||||
type PTemplate02 = "10" extends `${infer T extends `1${string}` | 10}` ? T : never; // "10"
|
||||
type PTemplate03 = "10" extends `${infer T extends `1${string}` | NumberLiteralEnum}` ? T : never; // "10"
|
||||
|
||||
// template-literal > bigint
|
||||
type PTemplate04 = "10" extends `${infer T extends `1${string}` | bigint}` ? T : never; // "10"
|
||||
|
||||
// template-literal > bigint-literal
|
||||
type PTemplate05 = "10" extends `${infer T extends `1${string}` | 10n}` ? T : never; // "10"
|
||||
|
||||
// template-literal > boolean
|
||||
type PTemplate06 = "true" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "true"
|
||||
type PTemplate07 = "false" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "false"
|
||||
|
||||
// template-literal > (boolean-literal | undefined | null)
|
||||
type PTemplate08 = "true" extends `${infer T extends `${"t"}${string}` | true}` ? T : never; // "true"
|
||||
type PTemplate09 = "false" extends `${infer T extends `${"f"}${string}` | false}` ? T : never; // "false"
|
||||
type PTemplate10 = "undefined" extends `${infer T extends `${"u"}${string}` | undefined}` ? T : never; // "undefined"
|
||||
type PTemplate11 = "null" extends `${infer T extends `${"n"}${string}` | null}` ? T : never; // "null"
|
||||
// #endregion template-literal
|
||||
|
||||
// #region string-literal
|
||||
// string-literal > number
|
||||
type PStringLiteral00 = "0" extends `${infer T extends "0" | number}` ? T : never; // "0"
|
||||
|
||||
// string-literal > enum
|
||||
type PStringLiteral01 = "0" extends `${infer T extends "0" | NonLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string-literal > (number-literal | number-literal-enum)
|
||||
type PStringLiteral02 = "0" extends `${infer T extends "0" | 0}` ? T : never; // "0"
|
||||
type PStringLiteral03 = "0" extends `${infer T extends "0" | NumberLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string-literal > bigint
|
||||
type PStringLiteral04 = "0" extends `${infer T extends "0" | bigint}` ? T : never; // "0"
|
||||
|
||||
// string-literal > bigint-literal
|
||||
type PStringLiteral05 = "0" extends `${infer T extends "0" | 0n}` ? T : never; // "0"
|
||||
|
||||
// string-literal > boolean
|
||||
type PStringLiteral06 = "true" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "true"
|
||||
type PStringLiteral07 = "false" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "false"
|
||||
|
||||
// string-literal > (boolean-literal | undefined | null)
|
||||
type PStringLiteral08 = "true" extends `${infer T extends "true" | true}` ? T : never; // "true"
|
||||
type PStringLiteral09 = "false" extends `${infer T extends "false" | false}` ? T : never; // "false"
|
||||
type PStringLiteral10 = "undefined" extends `${infer T extends "undefined" | undefined}` ? T : never; // "undefined"
|
||||
type PStringLiteral11 = "null" extends `${infer T extends "null" | null}` ? T : never; // "null"
|
||||
// #endregion string-literal
|
||||
|
||||
// #region string-literal-enum
|
||||
// string-literal-enum > number
|
||||
type PStringLiteralEnum00 = "0" extends `${infer T extends StringLiteralEnum | number}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > enum
|
||||
type PStringLiteralEnum01 = "0" extends `${infer T extends StringLiteralEnum | NonLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > (number-literal | number-literal-enum)
|
||||
type PStringLiteralEnum02 = "0" extends `${infer T extends StringLiteralEnum | 0}` ? T : never; // StringLiteralEnum.Zero
|
||||
type PStringLiteralEnum03 = "0" extends `${infer T extends StringLiteralEnum | NumberLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint
|
||||
type PStringLiteralEnum04 = "0" extends `${infer T extends StringLiteralEnum | bigint}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint-literal
|
||||
type PStringLiteralEnum05 = "0" extends `${infer T extends StringLiteralEnum | 0n}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > boolean
|
||||
type PStringLiteralEnum06 = "true" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.True
|
||||
type PStringLiteralEnum07 = "false" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.False
|
||||
|
||||
// string-literal-enum > (boolean-literal | undefined | null)
|
||||
type PStringLiteralEnum08 = "true" extends `${infer T extends StringLiteralEnum | true}` ? T : never; // StringLiteralEnum.True
|
||||
type PStringLiteralEnum09 = "false" extends `${infer T extends StringLiteralEnum | false}` ? T : never; // StringLiteralEnum.False
|
||||
type PStringLiteralEnum10 = "undefined" extends `${infer T extends StringLiteralEnum | undefined}` ? T : never; // StringLiteralEnum.Undefined
|
||||
type PStringLiteralEnum11 = "null" extends `${infer T extends StringLiteralEnum | null}` ? T : never; // StringLiteralEnum.Null
|
||||
// #endregion string-literal-enum
|
||||
|
||||
// #region number
|
||||
// number > enum
|
||||
type PNumber0 = "0" extends `${infer T extends number | NonLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// number > number-literal-enum
|
||||
type PNumber1 = "0" extends `${infer T extends number | NumberLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// number > bigint
|
||||
type PNumber2 = "0" extends `${infer T extends number | bigint}` ? T : never; // 0
|
||||
|
||||
// number > bigint-literal
|
||||
type PNumber3 = "0" extends `${infer T extends number | 0n}` ? T : never; // 0
|
||||
// #endregion number
|
||||
|
||||
// #region enum
|
||||
// enum > number-literal-enum
|
||||
type PEnum0 = "0" extends `${infer T extends NonLiteralEnum | NumberLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// enum > bigint
|
||||
type PEnum1 = "0" extends `${infer T extends NonLiteralEnum | bigint}` ? T : never; // 0
|
||||
|
||||
// enum > bigint-literal
|
||||
type PEnum2 = "0" extends `${infer T extends NonLiteralEnum | 0n}` ? T : never; // 0
|
||||
// #endregion enum
|
||||
|
||||
// #region number-literal
|
||||
// number-literal > bigint
|
||||
type PNumberLiteral0 = "0" extends `${infer T extends 0 | bigint}` ? T : never; // 0
|
||||
|
||||
// number-literal > bigint-literal
|
||||
type PNumberLiteral1 = "0" extends `${infer T extends 0 | 0n}` ? T : never; // 0
|
||||
// #endregion number-literal
|
||||
|
||||
// #region number-literal-enum
|
||||
// number-literal-enum > bigint
|
||||
type PNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum | bigint}` ? T : never; // NumberLiteralEnum.Zero
|
||||
|
||||
// number-literal-enum > bigint-literal
|
||||
type PNumberLiteralEnum1 = "0" extends `${infer T extends NumberLiteralEnum | 0n}` ? T : never; // NumberLiteralEnum.Zero
|
||||
// #endregion number-literal-enum
|
||||
|
||||
// non-matchable constituents are excluded
|
||||
type PExclude0 = "0" extends `${infer T extends "1" | number}` ? T : never; // 0
|
||||
type PExclude1 = "0" extends `${infer T extends `1${string}` | number}` ? T : never; // 0
|
||||
type PExclude2 = "0" extends `${infer T extends 1 | bigint}` ? T : never; // 0n
|
||||
type PExclude3 = "0" extends `${infer T extends NumberLiteralEnum.One | bigint}` ? T : never; // 0n
|
||||
type PExclude4 = "100000000000000000000000" extends `${infer T extends number | bigint}` ? T : never; // 100000000000000000000000n
|
||||
|
||||
// infer to prefix from string
|
||||
type TPrefix0 = "100" extends `${infer T extends number}${string}` ? T : never; // 1
|
||||
type TPrefix1 = "trueabc" extends `${infer T extends boolean}${string}` ? T : never; // boolean (T only receives 't', not the whole string)
|
||||
type TPrefix2 = `100:${string}` extends `${infer T extends number}:${string}` ? T : never; // 100 (T receives '100' because it scans until ':')
|
||||
|
||||
// can use union w/multiple branches to extract each possibility
|
||||
type ExtractPrimitives<T extends string> =
|
||||
| T
|
||||
| (T extends `${infer U extends number}` ? U : never)
|
||||
| (T extends `${infer U extends bigint}` ? U : never)
|
||||
| (T extends `${infer U extends boolean | null | undefined}` ? U : never)
|
||||
;
|
||||
|
||||
type TExtract0 = ExtractPrimitives<"100">; // "100" | 100 | 100n
|
||||
type TExtract1 = ExtractPrimitives<"1.1">; // "1.1" | 1.1
|
||||
type TExtract2 = ExtractPrimitives<"true">; // "true" | true
|
||||
|
||||
|
||||
|
||||
// example use case (based on old TypedObjects proposal):
|
||||
|
||||
// Use constrained `infer` in template literal to get ordinal indices as numbers:
|
||||
type IndexFor<S extends string> = S extends `${infer N extends number}` ? N : never;
|
||||
type IndicesOf<T> = IndexFor<Extract<keyof T, string>>; // ordinal indices as number literals
|
||||
|
||||
interface FieldDefinition {
|
||||
readonly name: string;
|
||||
readonly type: "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64";
|
||||
}
|
||||
|
||||
type FieldType<T extends FieldDefinition["type"]> =
|
||||
T extends "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64" ? number :
|
||||
T extends "f32" | "f64" ? bigint :
|
||||
never;
|
||||
|
||||
// Generates named members like `{ x: number, y: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectNamedMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[P in TDef[number]["name"]]: FieldType<Extract<TDef[number], { readonly name: P }>["type"]>;
|
||||
};
|
||||
|
||||
// Generates ordinal members like `{ 0: number, 1: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectOrdinalMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[I in Extract<keyof TDef, `${number}`>]: FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
};
|
||||
|
||||
// Default members
|
||||
interface TypedObjectMembers<TDef extends readonly FieldDefinition[]> {
|
||||
// get/set a field by name
|
||||
get<K extends TDef[number]["name"]>(key: K): FieldType<Extract<TDef[number], { readonly name: K }>["type"]>;
|
||||
set<K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], { readonly name: K }>["type"]>): void;
|
||||
|
||||
// get/set a field by index
|
||||
getIndex<I extends IndicesOf<TDef>>(index: I): FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
setIndex<I extends IndicesOf<TDef>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>): void;
|
||||
}
|
||||
|
||||
type TypedObject<TDef extends readonly FieldDefinition[]> =
|
||||
& TypedObjectMembers<TDef>
|
||||
& TypedObjectNamedMembers<TDef>
|
||||
& TypedObjectOrdinalMembers<TDef>;
|
||||
|
||||
// NOTE: type would normally be created from something like `const Point = TypedObject([...])` from which we would infer the type
|
||||
type Point = TypedObject<[
|
||||
{ name: "x", type: "f64" },
|
||||
{ name: "y", type: "f64" },
|
||||
]>;
|
||||
|
||||
declare const p: Point;
|
||||
p.getIndex(0); // ok, 0 is a valid index
|
||||
p.getIndex(1); // ok, 1 is a valid index
|
||||
p.getIndex(2); // error, 2 is not a valid index
|
||||
~
|
||||
!!! error TS2345: Argument of type '2' is not assignable to parameter of type '0 | 1'.
|
||||
|
||||
p.setIndex(0, 0); // ok, 0 is a valid index
|
||||
p.setIndex(1, 0); // ok, 1 is a valid index
|
||||
p.setIndex(2, 3); // error, 2 is not a valid index
|
||||
~
|
||||
!!! error TS2345: Argument of type '2' is not assignable to parameter of type '0 | 1'.
|
||||
|
||||
// function inference
|
||||
declare function f1<T extends string | number>(s: `**${T}**`): T;
|
||||
f1("**123**"); // "123"
|
||||
|
||||
declare function f2<T extends number>(s: `**${T}**`): T;
|
||||
f2("**123**"); // 123
|
||||
|
||||
declare function f3<T extends bigint>(s: `**${T}**`): T;
|
||||
f3("**123**"); // 123n
|
||||
|
||||
declare function f4<T extends boolean>(s: `**${T}**`): T;
|
||||
f4("**true**"); // true | "true"
|
||||
f4("**false**"); // false | "false"
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
//// [templateLiteralTypes4.ts]
|
||||
// infer from number
|
||||
type TNumber0 = "100" extends `${infer N extends number}` ? N : never; // 100
|
||||
type TNumber1 = "-100" extends `${infer N extends number}` ? N : never; // -100
|
||||
type TNumber2 = "1.1" extends `${infer N extends number}` ? N : never; // 1.1
|
||||
type TNumber3 = "8e-11" extends `${infer N extends number}` ? N : never; // 8e-11 (0.00000000008)
|
||||
type TNumber4 = "0x10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber5 = "0o10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber6 = "0b10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber7 = "10e2" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
type TNumber8 = "abcd" extends `${infer N extends number}` ? N : never; // never
|
||||
|
||||
// infer from bigint
|
||||
type TBigInt0 = "100" extends `${infer N extends bigint}` ? N : never; // 100n
|
||||
type TBigInt1 = "-100" extends `${infer N extends bigint}` ? N : never; // -100n
|
||||
type TBigInt2 = "0x10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt3 = "0o10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt4 = "0b10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
type TBigInt5 = "1.1" extends `${infer N extends bigint}` ? N : never; // never
|
||||
type TBigInt6 = "10e2" extends `${infer N extends bigint}` ? N : never; // never
|
||||
type TBigInt7 = "abcd" extends `${infer N extends bigint}` ? N : never; // never
|
||||
|
||||
// infer from boolean
|
||||
type TBoolean0 = "true" extends `${infer T extends boolean}` ? T : never; // true
|
||||
type TBoolean1 = "false" extends `${infer T extends boolean}` ? T : never; // false
|
||||
type TBoolean2 = "abcd" extends `${infer T extends boolean}` ? T : never; // never
|
||||
|
||||
// infer from null
|
||||
type TNull0 = "null" extends `${infer T extends null}` ? T : never; // null
|
||||
type TNull1 = "abcd" extends `${infer T extends null}` ? T : never; // never
|
||||
|
||||
// infer from undefined
|
||||
type TUndefined0 = "undefined" extends `${infer T extends undefined}` ? T : never; // undefined
|
||||
type TUndefined1 = "abcd" extends `${infer T extends undefined}` ? T : never; // never
|
||||
|
||||
// infer from literal enums
|
||||
const enum StringLiteralEnum { Zero = "0", True = "true", False = "false", Undefined = "undefined", Null = "null" }
|
||||
type TStringLiteralEnum0 = "0" extends `${infer T extends StringLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
const enum NumberLiteralEnum { Zero, One }
|
||||
type TNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum}` ? T : never; // NumberLiteralEnum.Zero
|
||||
|
||||
// infer from non-literal enums
|
||||
const enum NonLiteralEnum { Zero = NumberLiteralEnum.Zero, One = NumberLiteralEnum.One }
|
||||
type TNonLiteralEnum0 = "0" extends `${infer T extends NonLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// infer using priority:
|
||||
// string > template-literal > (string-literal | string-literal-enum) >
|
||||
// number > enum > (number-literal | number-literal-enum) >
|
||||
// bigint > bigint-literal >
|
||||
// boolean > (boolean-literal | undefined | null)
|
||||
|
||||
// #region string
|
||||
// string > string-literal-enum
|
||||
type PString00 = "0" extends `${infer T extends string | StringLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > number
|
||||
type PString01 = "0" extends `${infer T extends string | number}` ? T : never; // "0"
|
||||
|
||||
// string > enum
|
||||
type PString02 = "0" extends `${infer T extends string | NonLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > (number-literal | number-literal-enum)
|
||||
type PString03 = "0" extends `${infer T extends string | 0}` ? T : never; // "0"
|
||||
type PString04 = "0" extends `${infer T extends string | NumberLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string > bigint
|
||||
type PString05 = "0" extends `${infer T extends string | bigint}` ? T : never; // "0"
|
||||
|
||||
// string > bigint-literal
|
||||
type PString06 = "0" extends `${infer T extends string | 0n}` ? T : never; // "0"
|
||||
|
||||
// string > boolean
|
||||
type PString07 = "true" extends `${infer T extends string | boolean}` ? T : never; // "true"
|
||||
type PString08 = "false" extends `${infer T extends string | boolean}` ? T : never; // "false"
|
||||
|
||||
// string > (boolean-literal | undefined | null)
|
||||
type PString09 = "true" extends `${infer T extends string | true}` ? T : never; // "true"
|
||||
type PString10 = "false" extends `${infer T extends string | false}` ? T : never; // "false"
|
||||
type PString11 = "undefined" extends `${infer T extends string | undefined}` ? T : never; // "undefined"
|
||||
type PString12 = "null" extends `${infer T extends string | null}` ? T : never; // "null"
|
||||
// #endregion string
|
||||
|
||||
// #region template-literal
|
||||
// template-literal > number
|
||||
type PTemplate00 = "10" extends `${infer T extends `1${string}` | number}` ? T : never; // "10"
|
||||
|
||||
// template-literal > enum
|
||||
type PTemplate01 = "10" extends `${infer T extends `1${string}` | NonLiteralEnum}` ? T : never; // "10"
|
||||
|
||||
// template-literal > (number-literal | number-literal-enum)
|
||||
type PTemplate02 = "10" extends `${infer T extends `1${string}` | 10}` ? T : never; // "10"
|
||||
type PTemplate03 = "10" extends `${infer T extends `1${string}` | NumberLiteralEnum}` ? T : never; // "10"
|
||||
|
||||
// template-literal > bigint
|
||||
type PTemplate04 = "10" extends `${infer T extends `1${string}` | bigint}` ? T : never; // "10"
|
||||
|
||||
// template-literal > bigint-literal
|
||||
type PTemplate05 = "10" extends `${infer T extends `1${string}` | 10n}` ? T : never; // "10"
|
||||
|
||||
// template-literal > boolean
|
||||
type PTemplate06 = "true" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "true"
|
||||
type PTemplate07 = "false" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "false"
|
||||
|
||||
// template-literal > (boolean-literal | undefined | null)
|
||||
type PTemplate08 = "true" extends `${infer T extends `${"t"}${string}` | true}` ? T : never; // "true"
|
||||
type PTemplate09 = "false" extends `${infer T extends `${"f"}${string}` | false}` ? T : never; // "false"
|
||||
type PTemplate10 = "undefined" extends `${infer T extends `${"u"}${string}` | undefined}` ? T : never; // "undefined"
|
||||
type PTemplate11 = "null" extends `${infer T extends `${"n"}${string}` | null}` ? T : never; // "null"
|
||||
// #endregion template-literal
|
||||
|
||||
// #region string-literal
|
||||
// string-literal > number
|
||||
type PStringLiteral00 = "0" extends `${infer T extends "0" | number}` ? T : never; // "0"
|
||||
|
||||
// string-literal > enum
|
||||
type PStringLiteral01 = "0" extends `${infer T extends "0" | NonLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string-literal > (number-literal | number-literal-enum)
|
||||
type PStringLiteral02 = "0" extends `${infer T extends "0" | 0}` ? T : never; // "0"
|
||||
type PStringLiteral03 = "0" extends `${infer T extends "0" | NumberLiteralEnum}` ? T : never; // "0"
|
||||
|
||||
// string-literal > bigint
|
||||
type PStringLiteral04 = "0" extends `${infer T extends "0" | bigint}` ? T : never; // "0"
|
||||
|
||||
// string-literal > bigint-literal
|
||||
type PStringLiteral05 = "0" extends `${infer T extends "0" | 0n}` ? T : never; // "0"
|
||||
|
||||
// string-literal > boolean
|
||||
type PStringLiteral06 = "true" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "true"
|
||||
type PStringLiteral07 = "false" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "false"
|
||||
|
||||
// string-literal > (boolean-literal | undefined | null)
|
||||
type PStringLiteral08 = "true" extends `${infer T extends "true" | true}` ? T : never; // "true"
|
||||
type PStringLiteral09 = "false" extends `${infer T extends "false" | false}` ? T : never; // "false"
|
||||
type PStringLiteral10 = "undefined" extends `${infer T extends "undefined" | undefined}` ? T : never; // "undefined"
|
||||
type PStringLiteral11 = "null" extends `${infer T extends "null" | null}` ? T : never; // "null"
|
||||
// #endregion string-literal
|
||||
|
||||
// #region string-literal-enum
|
||||
// string-literal-enum > number
|
||||
type PStringLiteralEnum00 = "0" extends `${infer T extends StringLiteralEnum | number}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > enum
|
||||
type PStringLiteralEnum01 = "0" extends `${infer T extends StringLiteralEnum | NonLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > (number-literal | number-literal-enum)
|
||||
type PStringLiteralEnum02 = "0" extends `${infer T extends StringLiteralEnum | 0}` ? T : never; // StringLiteralEnum.Zero
|
||||
type PStringLiteralEnum03 = "0" extends `${infer T extends StringLiteralEnum | NumberLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint
|
||||
type PStringLiteralEnum04 = "0" extends `${infer T extends StringLiteralEnum | bigint}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint-literal
|
||||
type PStringLiteralEnum05 = "0" extends `${infer T extends StringLiteralEnum | 0n}` ? T : never; // StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > boolean
|
||||
type PStringLiteralEnum06 = "true" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.True
|
||||
type PStringLiteralEnum07 = "false" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.False
|
||||
|
||||
// string-literal-enum > (boolean-literal | undefined | null)
|
||||
type PStringLiteralEnum08 = "true" extends `${infer T extends StringLiteralEnum | true}` ? T : never; // StringLiteralEnum.True
|
||||
type PStringLiteralEnum09 = "false" extends `${infer T extends StringLiteralEnum | false}` ? T : never; // StringLiteralEnum.False
|
||||
type PStringLiteralEnum10 = "undefined" extends `${infer T extends StringLiteralEnum | undefined}` ? T : never; // StringLiteralEnum.Undefined
|
||||
type PStringLiteralEnum11 = "null" extends `${infer T extends StringLiteralEnum | null}` ? T : never; // StringLiteralEnum.Null
|
||||
// #endregion string-literal-enum
|
||||
|
||||
// #region number
|
||||
// number > enum
|
||||
type PNumber0 = "0" extends `${infer T extends number | NonLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// number > number-literal-enum
|
||||
type PNumber1 = "0" extends `${infer T extends number | NumberLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// number > bigint
|
||||
type PNumber2 = "0" extends `${infer T extends number | bigint}` ? T : never; // 0
|
||||
|
||||
// number > bigint-literal
|
||||
type PNumber3 = "0" extends `${infer T extends number | 0n}` ? T : never; // 0
|
||||
// #endregion number
|
||||
|
||||
// #region enum
|
||||
// enum > number-literal-enum
|
||||
type PEnum0 = "0" extends `${infer T extends NonLiteralEnum | NumberLiteralEnum}` ? T : never; // 0
|
||||
|
||||
// enum > bigint
|
||||
type PEnum1 = "0" extends `${infer T extends NonLiteralEnum | bigint}` ? T : never; // 0
|
||||
|
||||
// enum > bigint-literal
|
||||
type PEnum2 = "0" extends `${infer T extends NonLiteralEnum | 0n}` ? T : never; // 0
|
||||
// #endregion enum
|
||||
|
||||
// #region number-literal
|
||||
// number-literal > bigint
|
||||
type PNumberLiteral0 = "0" extends `${infer T extends 0 | bigint}` ? T : never; // 0
|
||||
|
||||
// number-literal > bigint-literal
|
||||
type PNumberLiteral1 = "0" extends `${infer T extends 0 | 0n}` ? T : never; // 0
|
||||
// #endregion number-literal
|
||||
|
||||
// #region number-literal-enum
|
||||
// number-literal-enum > bigint
|
||||
type PNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum | bigint}` ? T : never; // NumberLiteralEnum.Zero
|
||||
|
||||
// number-literal-enum > bigint-literal
|
||||
type PNumberLiteralEnum1 = "0" extends `${infer T extends NumberLiteralEnum | 0n}` ? T : never; // NumberLiteralEnum.Zero
|
||||
// #endregion number-literal-enum
|
||||
|
||||
// non-matchable constituents are excluded
|
||||
type PExclude0 = "0" extends `${infer T extends "1" | number}` ? T : never; // 0
|
||||
type PExclude1 = "0" extends `${infer T extends `1${string}` | number}` ? T : never; // 0
|
||||
type PExclude2 = "0" extends `${infer T extends 1 | bigint}` ? T : never; // 0n
|
||||
type PExclude3 = "0" extends `${infer T extends NumberLiteralEnum.One | bigint}` ? T : never; // 0n
|
||||
type PExclude4 = "100000000000000000000000" extends `${infer T extends number | bigint}` ? T : never; // 100000000000000000000000n
|
||||
|
||||
// infer to prefix from string
|
||||
type TPrefix0 = "100" extends `${infer T extends number}${string}` ? T : never; // 1
|
||||
type TPrefix1 = "trueabc" extends `${infer T extends boolean}${string}` ? T : never; // boolean (T only receives 't', not the whole string)
|
||||
type TPrefix2 = `100:${string}` extends `${infer T extends number}:${string}` ? T : never; // 100 (T receives '100' because it scans until ':')
|
||||
|
||||
// can use union w/multiple branches to extract each possibility
|
||||
type ExtractPrimitives<T extends string> =
|
||||
| T
|
||||
| (T extends `${infer U extends number}` ? U : never)
|
||||
| (T extends `${infer U extends bigint}` ? U : never)
|
||||
| (T extends `${infer U extends boolean | null | undefined}` ? U : never)
|
||||
;
|
||||
|
||||
type TExtract0 = ExtractPrimitives<"100">; // "100" | 100 | 100n
|
||||
type TExtract1 = ExtractPrimitives<"1.1">; // "1.1" | 1.1
|
||||
type TExtract2 = ExtractPrimitives<"true">; // "true" | true
|
||||
|
||||
|
||||
|
||||
// example use case (based on old TypedObjects proposal):
|
||||
|
||||
// Use constrained `infer` in template literal to get ordinal indices as numbers:
|
||||
type IndexFor<S extends string> = S extends `${infer N extends number}` ? N : never;
|
||||
type IndicesOf<T> = IndexFor<Extract<keyof T, string>>; // ordinal indices as number literals
|
||||
|
||||
interface FieldDefinition {
|
||||
readonly name: string;
|
||||
readonly type: "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64";
|
||||
}
|
||||
|
||||
type FieldType<T extends FieldDefinition["type"]> =
|
||||
T extends "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64" ? number :
|
||||
T extends "f32" | "f64" ? bigint :
|
||||
never;
|
||||
|
||||
// Generates named members like `{ x: number, y: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectNamedMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[P in TDef[number]["name"]]: FieldType<Extract<TDef[number], { readonly name: P }>["type"]>;
|
||||
};
|
||||
|
||||
// Generates ordinal members like `{ 0: number, 1: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectOrdinalMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[I in Extract<keyof TDef, `${number}`>]: FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
};
|
||||
|
||||
// Default members
|
||||
interface TypedObjectMembers<TDef extends readonly FieldDefinition[]> {
|
||||
// get/set a field by name
|
||||
get<K extends TDef[number]["name"]>(key: K): FieldType<Extract<TDef[number], { readonly name: K }>["type"]>;
|
||||
set<K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], { readonly name: K }>["type"]>): void;
|
||||
|
||||
// get/set a field by index
|
||||
getIndex<I extends IndicesOf<TDef>>(index: I): FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
setIndex<I extends IndicesOf<TDef>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>): void;
|
||||
}
|
||||
|
||||
type TypedObject<TDef extends readonly FieldDefinition[]> =
|
||||
& TypedObjectMembers<TDef>
|
||||
& TypedObjectNamedMembers<TDef>
|
||||
& TypedObjectOrdinalMembers<TDef>;
|
||||
|
||||
// NOTE: type would normally be created from something like `const Point = TypedObject([...])` from which we would infer the type
|
||||
type Point = TypedObject<[
|
||||
{ name: "x", type: "f64" },
|
||||
{ name: "y", type: "f64" },
|
||||
]>;
|
||||
|
||||
declare const p: Point;
|
||||
p.getIndex(0); // ok, 0 is a valid index
|
||||
p.getIndex(1); // ok, 1 is a valid index
|
||||
p.getIndex(2); // error, 2 is not a valid index
|
||||
|
||||
p.setIndex(0, 0); // ok, 0 is a valid index
|
||||
p.setIndex(1, 0); // ok, 1 is a valid index
|
||||
p.setIndex(2, 3); // error, 2 is not a valid index
|
||||
|
||||
// function inference
|
||||
declare function f1<T extends string | number>(s: `**${T}**`): T;
|
||||
f1("**123**"); // "123"
|
||||
|
||||
declare function f2<T extends number>(s: `**${T}**`): T;
|
||||
f2("**123**"); // 123
|
||||
|
||||
declare function f3<T extends bigint>(s: `**${T}**`): T;
|
||||
f3("**123**"); // 123n
|
||||
|
||||
declare function f4<T extends boolean>(s: `**${T}**`): T;
|
||||
f4("**true**"); // true | "true"
|
||||
f4("**false**"); // false | "false"
|
||||
|
||||
|
||||
//// [templateLiteralTypes4.js]
|
||||
"use strict";
|
||||
p.getIndex(0); // ok, 0 is a valid index
|
||||
p.getIndex(1); // ok, 1 is a valid index
|
||||
p.getIndex(2); // error, 2 is not a valid index
|
||||
p.setIndex(0, 0); // ok, 0 is a valid index
|
||||
p.setIndex(1, 0); // ok, 1 is a valid index
|
||||
p.setIndex(2, 3); // error, 2 is not a valid index
|
||||
f1("**123**"); // "123"
|
||||
f2("**123**"); // 123
|
||||
f3("**123**"); // 123n
|
||||
f4("**true**"); // true | "true"
|
||||
f4("**false**"); // false | "false"
|
||||
|
||||
|
||||
//// [templateLiteralTypes4.d.ts]
|
||||
declare type TNumber0 = "100" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber1 = "-100" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber2 = "1.1" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber3 = "8e-11" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber4 = "0x10" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber5 = "0o10" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber6 = "0b10" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber7 = "10e2" extends `${infer N extends number}` ? N : never;
|
||||
declare type TNumber8 = "abcd" extends `${infer N extends number}` ? N : never;
|
||||
declare type TBigInt0 = "100" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt1 = "-100" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt2 = "0x10" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt3 = "0o10" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt4 = "0b10" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt5 = "1.1" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt6 = "10e2" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBigInt7 = "abcd" extends `${infer N extends bigint}` ? N : never;
|
||||
declare type TBoolean0 = "true" extends `${infer T extends boolean}` ? T : never;
|
||||
declare type TBoolean1 = "false" extends `${infer T extends boolean}` ? T : never;
|
||||
declare type TBoolean2 = "abcd" extends `${infer T extends boolean}` ? T : never;
|
||||
declare type TNull0 = "null" extends `${infer T extends null}` ? T : never;
|
||||
declare type TNull1 = "abcd" extends `${infer T extends null}` ? T : never;
|
||||
declare type TUndefined0 = "undefined" extends `${infer T extends undefined}` ? T : never;
|
||||
declare type TUndefined1 = "abcd" extends `${infer T extends undefined}` ? T : never;
|
||||
declare const enum StringLiteralEnum {
|
||||
Zero = "0",
|
||||
True = "true",
|
||||
False = "false",
|
||||
Undefined = "undefined",
|
||||
Null = "null"
|
||||
}
|
||||
declare type TStringLiteralEnum0 = "0" extends `${infer T extends StringLiteralEnum}` ? T : never;
|
||||
declare const enum NumberLiteralEnum {
|
||||
Zero = 0,
|
||||
One = 1
|
||||
}
|
||||
declare type TNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum}` ? T : never;
|
||||
declare const enum NonLiteralEnum {
|
||||
Zero = 0,
|
||||
One = 1
|
||||
}
|
||||
declare type TNonLiteralEnum0 = "0" extends `${infer T extends NonLiteralEnum}` ? T : never;
|
||||
declare type PString00 = "0" extends `${infer T extends string | StringLiteralEnum}` ? T : never;
|
||||
declare type PString01 = "0" extends `${infer T extends string | number}` ? T : never;
|
||||
declare type PString02 = "0" extends `${infer T extends string | NonLiteralEnum}` ? T : never;
|
||||
declare type PString03 = "0" extends `${infer T extends string | 0}` ? T : never;
|
||||
declare type PString04 = "0" extends `${infer T extends string | NumberLiteralEnum}` ? T : never;
|
||||
declare type PString05 = "0" extends `${infer T extends string | bigint}` ? T : never;
|
||||
declare type PString06 = "0" extends `${infer T extends string | 0n}` ? T : never;
|
||||
declare type PString07 = "true" extends `${infer T extends string | boolean}` ? T : never;
|
||||
declare type PString08 = "false" extends `${infer T extends string | boolean}` ? T : never;
|
||||
declare type PString09 = "true" extends `${infer T extends string | true}` ? T : never;
|
||||
declare type PString10 = "false" extends `${infer T extends string | false}` ? T : never;
|
||||
declare type PString11 = "undefined" extends `${infer T extends string | undefined}` ? T : never;
|
||||
declare type PString12 = "null" extends `${infer T extends string | null}` ? T : never;
|
||||
declare type PTemplate00 = "10" extends `${infer T extends `1${string}` | number}` ? T : never;
|
||||
declare type PTemplate01 = "10" extends `${infer T extends `1${string}` | NonLiteralEnum}` ? T : never;
|
||||
declare type PTemplate02 = "10" extends `${infer T extends `1${string}` | 10}` ? T : never;
|
||||
declare type PTemplate03 = "10" extends `${infer T extends `1${string}` | NumberLiteralEnum}` ? T : never;
|
||||
declare type PTemplate04 = "10" extends `${infer T extends `1${string}` | bigint}` ? T : never;
|
||||
declare type PTemplate05 = "10" extends `${infer T extends `1${string}` | 10n}` ? T : never;
|
||||
declare type PTemplate06 = "true" extends `${infer T extends `${string}e` | boolean}` ? T : never;
|
||||
declare type PTemplate07 = "false" extends `${infer T extends `${string}e` | boolean}` ? T : never;
|
||||
declare type PTemplate08 = "true" extends `${infer T extends `${"t"}${string}` | true}` ? T : never;
|
||||
declare type PTemplate09 = "false" extends `${infer T extends `${"f"}${string}` | false}` ? T : never;
|
||||
declare type PTemplate10 = "undefined" extends `${infer T extends `${"u"}${string}` | undefined}` ? T : never;
|
||||
declare type PTemplate11 = "null" extends `${infer T extends `${"n"}${string}` | null}` ? T : never;
|
||||
declare type PStringLiteral00 = "0" extends `${infer T extends "0" | number}` ? T : never;
|
||||
declare type PStringLiteral01 = "0" extends `${infer T extends "0" | NonLiteralEnum}` ? T : never;
|
||||
declare type PStringLiteral02 = "0" extends `${infer T extends "0" | 0}` ? T : never;
|
||||
declare type PStringLiteral03 = "0" extends `${infer T extends "0" | NumberLiteralEnum}` ? T : never;
|
||||
declare type PStringLiteral04 = "0" extends `${infer T extends "0" | bigint}` ? T : never;
|
||||
declare type PStringLiteral05 = "0" extends `${infer T extends "0" | 0n}` ? T : never;
|
||||
declare type PStringLiteral06 = "true" extends `${infer T extends "true" | "false" | boolean}` ? T : never;
|
||||
declare type PStringLiteral07 = "false" extends `${infer T extends "true" | "false" | boolean}` ? T : never;
|
||||
declare type PStringLiteral08 = "true" extends `${infer T extends "true" | true}` ? T : never;
|
||||
declare type PStringLiteral09 = "false" extends `${infer T extends "false" | false}` ? T : never;
|
||||
declare type PStringLiteral10 = "undefined" extends `${infer T extends "undefined" | undefined}` ? T : never;
|
||||
declare type PStringLiteral11 = "null" extends `${infer T extends "null" | null}` ? T : never;
|
||||
declare type PStringLiteralEnum00 = "0" extends `${infer T extends StringLiteralEnum | number}` ? T : never;
|
||||
declare type PStringLiteralEnum01 = "0" extends `${infer T extends StringLiteralEnum | NonLiteralEnum}` ? T : never;
|
||||
declare type PStringLiteralEnum02 = "0" extends `${infer T extends StringLiteralEnum | 0}` ? T : never;
|
||||
declare type PStringLiteralEnum03 = "0" extends `${infer T extends StringLiteralEnum | NumberLiteralEnum}` ? T : never;
|
||||
declare type PStringLiteralEnum04 = "0" extends `${infer T extends StringLiteralEnum | bigint}` ? T : never;
|
||||
declare type PStringLiteralEnum05 = "0" extends `${infer T extends StringLiteralEnum | 0n}` ? T : never;
|
||||
declare type PStringLiteralEnum06 = "true" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never;
|
||||
declare type PStringLiteralEnum07 = "false" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never;
|
||||
declare type PStringLiteralEnum08 = "true" extends `${infer T extends StringLiteralEnum | true}` ? T : never;
|
||||
declare type PStringLiteralEnum09 = "false" extends `${infer T extends StringLiteralEnum | false}` ? T : never;
|
||||
declare type PStringLiteralEnum10 = "undefined" extends `${infer T extends StringLiteralEnum | undefined}` ? T : never;
|
||||
declare type PStringLiteralEnum11 = "null" extends `${infer T extends StringLiteralEnum | null}` ? T : never;
|
||||
declare type PNumber0 = "0" extends `${infer T extends number | NonLiteralEnum}` ? T : never;
|
||||
declare type PNumber1 = "0" extends `${infer T extends number | NumberLiteralEnum}` ? T : never;
|
||||
declare type PNumber2 = "0" extends `${infer T extends number | bigint}` ? T : never;
|
||||
declare type PNumber3 = "0" extends `${infer T extends number | 0n}` ? T : never;
|
||||
declare type PEnum0 = "0" extends `${infer T extends NonLiteralEnum | NumberLiteralEnum}` ? T : never;
|
||||
declare type PEnum1 = "0" extends `${infer T extends NonLiteralEnum | bigint}` ? T : never;
|
||||
declare type PEnum2 = "0" extends `${infer T extends NonLiteralEnum | 0n}` ? T : never;
|
||||
declare type PNumberLiteral0 = "0" extends `${infer T extends 0 | bigint}` ? T : never;
|
||||
declare type PNumberLiteral1 = "0" extends `${infer T extends 0 | 0n}` ? T : never;
|
||||
declare type PNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum | bigint}` ? T : never;
|
||||
declare type PNumberLiteralEnum1 = "0" extends `${infer T extends NumberLiteralEnum | 0n}` ? T : never;
|
||||
declare type PExclude0 = "0" extends `${infer T extends "1" | number}` ? T : never;
|
||||
declare type PExclude1 = "0" extends `${infer T extends `1${string}` | number}` ? T : never;
|
||||
declare type PExclude2 = "0" extends `${infer T extends 1 | bigint}` ? T : never;
|
||||
declare type PExclude3 = "0" extends `${infer T extends NumberLiteralEnum.One | bigint}` ? T : never;
|
||||
declare type PExclude4 = "100000000000000000000000" extends `${infer T extends number | bigint}` ? T : never;
|
||||
declare type TPrefix0 = "100" extends `${infer T extends number}${string}` ? T : never;
|
||||
declare type TPrefix1 = "trueabc" extends `${infer T extends boolean}${string}` ? T : never;
|
||||
declare type TPrefix2 = `100:${string}` extends `${infer T extends number}:${string}` ? T : never;
|
||||
declare type ExtractPrimitives<T extends string> = T | (T extends `${infer U extends number}` ? U : never) | (T extends `${infer U extends bigint}` ? U : never) | (T extends `${infer U extends boolean | null | undefined}` ? U : never);
|
||||
declare type TExtract0 = ExtractPrimitives<"100">;
|
||||
declare type TExtract1 = ExtractPrimitives<"1.1">;
|
||||
declare type TExtract2 = ExtractPrimitives<"true">;
|
||||
declare type IndexFor<S extends string> = S extends `${infer N extends number}` ? N : never;
|
||||
declare type IndicesOf<T> = IndexFor<Extract<keyof T, string>>;
|
||||
interface FieldDefinition {
|
||||
readonly name: string;
|
||||
readonly type: "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64";
|
||||
}
|
||||
declare type FieldType<T extends FieldDefinition["type"]> = T extends "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64" ? number : T extends "f32" | "f64" ? bigint : never;
|
||||
declare type TypedObjectNamedMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[P in TDef[number]["name"]]: FieldType<Extract<TDef[number], {
|
||||
readonly name: P;
|
||||
}>["type"]>;
|
||||
};
|
||||
declare type TypedObjectOrdinalMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
[I in Extract<keyof TDef, `${number}`>]: FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
};
|
||||
interface TypedObjectMembers<TDef extends readonly FieldDefinition[]> {
|
||||
get<K extends TDef[number]["name"]>(key: K): FieldType<Extract<TDef[number], {
|
||||
readonly name: K;
|
||||
}>["type"]>;
|
||||
set<K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], {
|
||||
readonly name: K;
|
||||
}>["type"]>): void;
|
||||
getIndex<I extends IndicesOf<TDef>>(index: I): FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
setIndex<I extends IndicesOf<TDef>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>): void;
|
||||
}
|
||||
declare type TypedObject<TDef extends readonly FieldDefinition[]> = TypedObjectMembers<TDef> & TypedObjectNamedMembers<TDef> & TypedObjectOrdinalMembers<TDef>;
|
||||
declare type Point = TypedObject<[
|
||||
{
|
||||
name: "x";
|
||||
type: "f64";
|
||||
},
|
||||
{
|
||||
name: "y";
|
||||
type: "f64";
|
||||
}
|
||||
]>;
|
||||
declare const p: Point;
|
||||
declare function f1<T extends string | number>(s: `**${T}**`): T;
|
||||
declare function f2<T extends number>(s: `**${T}**`): T;
|
||||
declare function f3<T extends bigint>(s: `**${T}**`): T;
|
||||
declare function f4<T extends boolean>(s: `**${T}**`): T;
|
||||
@@ -0,0 +1,898 @@
|
||||
=== tests/cases/conformance/types/literal/templateLiteralTypes4.ts ===
|
||||
// infer from number
|
||||
type TNumber0 = "100" extends `${infer N extends number}` ? N : never; // 100
|
||||
>TNumber0 : Symbol(TNumber0, Decl(templateLiteralTypes4.ts, 0, 0))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 1, 38))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 1, 38))
|
||||
|
||||
type TNumber1 = "-100" extends `${infer N extends number}` ? N : never; // -100
|
||||
>TNumber1 : Symbol(TNumber1, Decl(templateLiteralTypes4.ts, 1, 70))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 2, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 2, 39))
|
||||
|
||||
type TNumber2 = "1.1" extends `${infer N extends number}` ? N : never; // 1.1
|
||||
>TNumber2 : Symbol(TNumber2, Decl(templateLiteralTypes4.ts, 2, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 3, 38))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 3, 38))
|
||||
|
||||
type TNumber3 = "8e-11" extends `${infer N extends number}` ? N : never; // 8e-11 (0.00000000008)
|
||||
>TNumber3 : Symbol(TNumber3, Decl(templateLiteralTypes4.ts, 3, 70))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 4, 40))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 4, 40))
|
||||
|
||||
type TNumber4 = "0x10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber4 : Symbol(TNumber4, Decl(templateLiteralTypes4.ts, 4, 72))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 5, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 5, 39))
|
||||
|
||||
type TNumber5 = "0o10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber5 : Symbol(TNumber5, Decl(templateLiteralTypes4.ts, 5, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 6, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 6, 39))
|
||||
|
||||
type TNumber6 = "0b10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber6 : Symbol(TNumber6, Decl(templateLiteralTypes4.ts, 6, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 7, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 7, 39))
|
||||
|
||||
type TNumber7 = "10e2" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber7 : Symbol(TNumber7, Decl(templateLiteralTypes4.ts, 7, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 8, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 8, 39))
|
||||
|
||||
type TNumber8 = "abcd" extends `${infer N extends number}` ? N : never; // never
|
||||
>TNumber8 : Symbol(TNumber8, Decl(templateLiteralTypes4.ts, 8, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 9, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 9, 39))
|
||||
|
||||
// infer from bigint
|
||||
type TBigInt0 = "100" extends `${infer N extends bigint}` ? N : never; // 100n
|
||||
>TBigInt0 : Symbol(TBigInt0, Decl(templateLiteralTypes4.ts, 9, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 12, 38))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 12, 38))
|
||||
|
||||
type TBigInt1 = "-100" extends `${infer N extends bigint}` ? N : never; // -100n
|
||||
>TBigInt1 : Symbol(TBigInt1, Decl(templateLiteralTypes4.ts, 12, 70))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 13, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 13, 39))
|
||||
|
||||
type TBigInt2 = "0x10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt2 : Symbol(TBigInt2, Decl(templateLiteralTypes4.ts, 13, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 14, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 14, 39))
|
||||
|
||||
type TBigInt3 = "0o10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt3 : Symbol(TBigInt3, Decl(templateLiteralTypes4.ts, 14, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 15, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 15, 39))
|
||||
|
||||
type TBigInt4 = "0b10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt4 : Symbol(TBigInt4, Decl(templateLiteralTypes4.ts, 15, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 16, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 16, 39))
|
||||
|
||||
type TBigInt5 = "1.1" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt5 : Symbol(TBigInt5, Decl(templateLiteralTypes4.ts, 16, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 17, 38))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 17, 38))
|
||||
|
||||
type TBigInt6 = "10e2" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt6 : Symbol(TBigInt6, Decl(templateLiteralTypes4.ts, 17, 70))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 18, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 18, 39))
|
||||
|
||||
type TBigInt7 = "abcd" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt7 : Symbol(TBigInt7, Decl(templateLiteralTypes4.ts, 18, 71))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 19, 39))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 19, 39))
|
||||
|
||||
// infer from boolean
|
||||
type TBoolean0 = "true" extends `${infer T extends boolean}` ? T : never; // true
|
||||
>TBoolean0 : Symbol(TBoolean0, Decl(templateLiteralTypes4.ts, 19, 71))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 22, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 22, 40))
|
||||
|
||||
type TBoolean1 = "false" extends `${infer T extends boolean}` ? T : never; // false
|
||||
>TBoolean1 : Symbol(TBoolean1, Decl(templateLiteralTypes4.ts, 22, 73))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 23, 41))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 23, 41))
|
||||
|
||||
type TBoolean2 = "abcd" extends `${infer T extends boolean}` ? T : never; // never
|
||||
>TBoolean2 : Symbol(TBoolean2, Decl(templateLiteralTypes4.ts, 23, 74))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 24, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 24, 40))
|
||||
|
||||
// infer from null
|
||||
type TNull0 = "null" extends `${infer T extends null}` ? T : never; // null
|
||||
>TNull0 : Symbol(TNull0, Decl(templateLiteralTypes4.ts, 24, 73))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 27, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 27, 37))
|
||||
|
||||
type TNull1 = "abcd" extends `${infer T extends null}` ? T : never; // never
|
||||
>TNull1 : Symbol(TNull1, Decl(templateLiteralTypes4.ts, 27, 67))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 28, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 28, 37))
|
||||
|
||||
// infer from undefined
|
||||
type TUndefined0 = "undefined" extends `${infer T extends undefined}` ? T : never; // undefined
|
||||
>TUndefined0 : Symbol(TUndefined0, Decl(templateLiteralTypes4.ts, 28, 67))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 31, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 31, 47))
|
||||
|
||||
type TUndefined1 = "abcd" extends `${infer T extends undefined}` ? T : never; // never
|
||||
>TUndefined1 : Symbol(TUndefined1, Decl(templateLiteralTypes4.ts, 31, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 32, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 32, 42))
|
||||
|
||||
// infer from literal enums
|
||||
const enum StringLiteralEnum { Zero = "0", True = "true", False = "false", Undefined = "undefined", Null = "null" }
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>Zero : Symbol(StringLiteralEnum.Zero, Decl(templateLiteralTypes4.ts, 35, 30))
|
||||
>True : Symbol(StringLiteralEnum.True, Decl(templateLiteralTypes4.ts, 35, 42))
|
||||
>False : Symbol(StringLiteralEnum.False, Decl(templateLiteralTypes4.ts, 35, 57))
|
||||
>Undefined : Symbol(StringLiteralEnum.Undefined, Decl(templateLiteralTypes4.ts, 35, 74))
|
||||
>Null : Symbol(StringLiteralEnum.Null, Decl(templateLiteralTypes4.ts, 35, 99))
|
||||
|
||||
type TStringLiteralEnum0 = "0" extends `${infer T extends StringLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>TStringLiteralEnum0 : Symbol(TStringLiteralEnum0, Decl(templateLiteralTypes4.ts, 35, 115))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 36, 47))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 36, 47))
|
||||
|
||||
const enum NumberLiteralEnum { Zero, One }
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>Zero : Symbol(NumberLiteralEnum.Zero, Decl(templateLiteralTypes4.ts, 38, 30))
|
||||
>One : Symbol(NumberLiteralEnum.One, Decl(templateLiteralTypes4.ts, 38, 36))
|
||||
|
||||
type TNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>TNumberLiteralEnum0 : Symbol(TNumberLiteralEnum0, Decl(templateLiteralTypes4.ts, 38, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 39, 47))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 39, 47))
|
||||
|
||||
// infer from non-literal enums
|
||||
const enum NonLiteralEnum { Zero = NumberLiteralEnum.Zero, One = NumberLiteralEnum.One }
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>Zero : Symbol(NonLiteralEnum.Zero, Decl(templateLiteralTypes4.ts, 42, 27))
|
||||
>NumberLiteralEnum.Zero : Symbol(NumberLiteralEnum.Zero, Decl(templateLiteralTypes4.ts, 38, 30))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>Zero : Symbol(NumberLiteralEnum.Zero, Decl(templateLiteralTypes4.ts, 38, 30))
|
||||
>One : Symbol(NonLiteralEnum.One, Decl(templateLiteralTypes4.ts, 42, 58))
|
||||
>NumberLiteralEnum.One : Symbol(NumberLiteralEnum.One, Decl(templateLiteralTypes4.ts, 38, 36))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>One : Symbol(NumberLiteralEnum.One, Decl(templateLiteralTypes4.ts, 38, 36))
|
||||
|
||||
type TNonLiteralEnum0 = "0" extends `${infer T extends NonLiteralEnum}` ? T : never; // 0
|
||||
>TNonLiteralEnum0 : Symbol(TNonLiteralEnum0, Decl(templateLiteralTypes4.ts, 42, 88))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 43, 44))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 43, 44))
|
||||
|
||||
// infer using priority:
|
||||
// string > template-literal > (string-literal | string-literal-enum) >
|
||||
// number > enum > (number-literal | number-literal-enum) >
|
||||
// bigint > bigint-literal >
|
||||
// boolean > (boolean-literal | undefined | null)
|
||||
|
||||
// #region string
|
||||
// string > string-literal-enum
|
||||
type PString00 = "0" extends `${infer T extends string | StringLiteralEnum}` ? T : never; // "0"
|
||||
>PString00 : Symbol(PString00, Decl(templateLiteralTypes4.ts, 43, 84))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 53, 37))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 53, 37))
|
||||
|
||||
// string > number
|
||||
type PString01 = "0" extends `${infer T extends string | number}` ? T : never; // "0"
|
||||
>PString01 : Symbol(PString01, Decl(templateLiteralTypes4.ts, 53, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 56, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 56, 37))
|
||||
|
||||
// string > enum
|
||||
type PString02 = "0" extends `${infer T extends string | NonLiteralEnum}` ? T : never; // "0"
|
||||
>PString02 : Symbol(PString02, Decl(templateLiteralTypes4.ts, 56, 78))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 59, 37))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 59, 37))
|
||||
|
||||
// string > (number-literal | number-literal-enum)
|
||||
type PString03 = "0" extends `${infer T extends string | 0}` ? T : never; // "0"
|
||||
>PString03 : Symbol(PString03, Decl(templateLiteralTypes4.ts, 59, 86))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 62, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 62, 37))
|
||||
|
||||
type PString04 = "0" extends `${infer T extends string | NumberLiteralEnum}` ? T : never; // "0"
|
||||
>PString04 : Symbol(PString04, Decl(templateLiteralTypes4.ts, 62, 73))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 63, 37))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 63, 37))
|
||||
|
||||
// string > bigint
|
||||
type PString05 = "0" extends `${infer T extends string | bigint}` ? T : never; // "0"
|
||||
>PString05 : Symbol(PString05, Decl(templateLiteralTypes4.ts, 63, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 66, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 66, 37))
|
||||
|
||||
// string > bigint-literal
|
||||
type PString06 = "0" extends `${infer T extends string | 0n}` ? T : never; // "0"
|
||||
>PString06 : Symbol(PString06, Decl(templateLiteralTypes4.ts, 66, 78))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 69, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 69, 37))
|
||||
|
||||
// string > boolean
|
||||
type PString07 = "true" extends `${infer T extends string | boolean}` ? T : never; // "true"
|
||||
>PString07 : Symbol(PString07, Decl(templateLiteralTypes4.ts, 69, 74))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 72, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 72, 40))
|
||||
|
||||
type PString08 = "false" extends `${infer T extends string | boolean}` ? T : never; // "false"
|
||||
>PString08 : Symbol(PString08, Decl(templateLiteralTypes4.ts, 72, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 73, 41))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 73, 41))
|
||||
|
||||
// string > (boolean-literal | undefined | null)
|
||||
type PString09 = "true" extends `${infer T extends string | true}` ? T : never; // "true"
|
||||
>PString09 : Symbol(PString09, Decl(templateLiteralTypes4.ts, 73, 83))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 76, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 76, 40))
|
||||
|
||||
type PString10 = "false" extends `${infer T extends string | false}` ? T : never; // "false"
|
||||
>PString10 : Symbol(PString10, Decl(templateLiteralTypes4.ts, 76, 79))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 77, 41))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 77, 41))
|
||||
|
||||
type PString11 = "undefined" extends `${infer T extends string | undefined}` ? T : never; // "undefined"
|
||||
>PString11 : Symbol(PString11, Decl(templateLiteralTypes4.ts, 77, 81))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 78, 45))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 78, 45))
|
||||
|
||||
type PString12 = "null" extends `${infer T extends string | null}` ? T : never; // "null"
|
||||
>PString12 : Symbol(PString12, Decl(templateLiteralTypes4.ts, 78, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 79, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 79, 40))
|
||||
|
||||
// #endregion string
|
||||
|
||||
// #region template-literal
|
||||
// template-literal > number
|
||||
type PTemplate00 = "10" extends `${infer T extends `1${string}` | number}` ? T : never; // "10"
|
||||
>PTemplate00 : Symbol(PTemplate00, Decl(templateLiteralTypes4.ts, 79, 79))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 84, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 84, 40))
|
||||
|
||||
// template-literal > enum
|
||||
type PTemplate01 = "10" extends `${infer T extends `1${string}` | NonLiteralEnum}` ? T : never; // "10"
|
||||
>PTemplate01 : Symbol(PTemplate01, Decl(templateLiteralTypes4.ts, 84, 87))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 87, 40))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 87, 40))
|
||||
|
||||
// template-literal > (number-literal | number-literal-enum)
|
||||
type PTemplate02 = "10" extends `${infer T extends `1${string}` | 10}` ? T : never; // "10"
|
||||
>PTemplate02 : Symbol(PTemplate02, Decl(templateLiteralTypes4.ts, 87, 95))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 90, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 90, 40))
|
||||
|
||||
type PTemplate03 = "10" extends `${infer T extends `1${string}` | NumberLiteralEnum}` ? T : never; // "10"
|
||||
>PTemplate03 : Symbol(PTemplate03, Decl(templateLiteralTypes4.ts, 90, 83))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 91, 40))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 91, 40))
|
||||
|
||||
// template-literal > bigint
|
||||
type PTemplate04 = "10" extends `${infer T extends `1${string}` | bigint}` ? T : never; // "10"
|
||||
>PTemplate04 : Symbol(PTemplate04, Decl(templateLiteralTypes4.ts, 91, 98))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 94, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 94, 40))
|
||||
|
||||
// template-literal > bigint-literal
|
||||
type PTemplate05 = "10" extends `${infer T extends `1${string}` | 10n}` ? T : never; // "10"
|
||||
>PTemplate05 : Symbol(PTemplate05, Decl(templateLiteralTypes4.ts, 94, 87))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 97, 40))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 97, 40))
|
||||
|
||||
// template-literal > boolean
|
||||
type PTemplate06 = "true" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "true"
|
||||
>PTemplate06 : Symbol(PTemplate06, Decl(templateLiteralTypes4.ts, 97, 84))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 100, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 100, 42))
|
||||
|
||||
type PTemplate07 = "false" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "false"
|
||||
>PTemplate07 : Symbol(PTemplate07, Decl(templateLiteralTypes4.ts, 100, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 101, 43))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 101, 43))
|
||||
|
||||
// template-literal > (boolean-literal | undefined | null)
|
||||
type PTemplate08 = "true" extends `${infer T extends `${"t"}${string}` | true}` ? T : never; // "true"
|
||||
>PTemplate08 : Symbol(PTemplate08, Decl(templateLiteralTypes4.ts, 101, 91))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 104, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 104, 42))
|
||||
|
||||
type PTemplate09 = "false" extends `${infer T extends `${"f"}${string}` | false}` ? T : never; // "false"
|
||||
>PTemplate09 : Symbol(PTemplate09, Decl(templateLiteralTypes4.ts, 104, 92))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 105, 43))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 105, 43))
|
||||
|
||||
type PTemplate10 = "undefined" extends `${infer T extends `${"u"}${string}` | undefined}` ? T : never; // "undefined"
|
||||
>PTemplate10 : Symbol(PTemplate10, Decl(templateLiteralTypes4.ts, 105, 94))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 106, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 106, 47))
|
||||
|
||||
type PTemplate11 = "null" extends `${infer T extends `${"n"}${string}` | null}` ? T : never; // "null"
|
||||
>PTemplate11 : Symbol(PTemplate11, Decl(templateLiteralTypes4.ts, 106, 102))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 107, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 107, 42))
|
||||
|
||||
// #endregion template-literal
|
||||
|
||||
// #region string-literal
|
||||
// string-literal > number
|
||||
type PStringLiteral00 = "0" extends `${infer T extends "0" | number}` ? T : never; // "0"
|
||||
>PStringLiteral00 : Symbol(PStringLiteral00, Decl(templateLiteralTypes4.ts, 107, 92))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 112, 44))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 112, 44))
|
||||
|
||||
// string-literal > enum
|
||||
type PStringLiteral01 = "0" extends `${infer T extends "0" | NonLiteralEnum}` ? T : never; // "0"
|
||||
>PStringLiteral01 : Symbol(PStringLiteral01, Decl(templateLiteralTypes4.ts, 112, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 115, 44))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 115, 44))
|
||||
|
||||
// string-literal > (number-literal | number-literal-enum)
|
||||
type PStringLiteral02 = "0" extends `${infer T extends "0" | 0}` ? T : never; // "0"
|
||||
>PStringLiteral02 : Symbol(PStringLiteral02, Decl(templateLiteralTypes4.ts, 115, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 118, 44))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 118, 44))
|
||||
|
||||
type PStringLiteral03 = "0" extends `${infer T extends "0" | NumberLiteralEnum}` ? T : never; // "0"
|
||||
>PStringLiteral03 : Symbol(PStringLiteral03, Decl(templateLiteralTypes4.ts, 118, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 119, 44))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 119, 44))
|
||||
|
||||
// string-literal > bigint
|
||||
type PStringLiteral04 = "0" extends `${infer T extends "0" | bigint}` ? T : never; // "0"
|
||||
>PStringLiteral04 : Symbol(PStringLiteral04, Decl(templateLiteralTypes4.ts, 119, 93))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 122, 44))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 122, 44))
|
||||
|
||||
// string-literal > bigint-literal
|
||||
type PStringLiteral05 = "0" extends `${infer T extends "0" | 0n}` ? T : never; // "0"
|
||||
>PStringLiteral05 : Symbol(PStringLiteral05, Decl(templateLiteralTypes4.ts, 122, 82))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 125, 44))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 125, 44))
|
||||
|
||||
// string-literal > boolean
|
||||
type PStringLiteral06 = "true" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "true"
|
||||
>PStringLiteral06 : Symbol(PStringLiteral06, Decl(templateLiteralTypes4.ts, 125, 78))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 128, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 128, 47))
|
||||
|
||||
type PStringLiteral07 = "false" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "false"
|
||||
>PStringLiteral07 : Symbol(PStringLiteral07, Decl(templateLiteralTypes4.ts, 128, 99))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 129, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 129, 48))
|
||||
|
||||
// string-literal > (boolean-literal | undefined | null)
|
||||
type PStringLiteral08 = "true" extends `${infer T extends "true" | true}` ? T : never; // "true"
|
||||
>PStringLiteral08 : Symbol(PStringLiteral08, Decl(templateLiteralTypes4.ts, 129, 100))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 132, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 132, 47))
|
||||
|
||||
type PStringLiteral09 = "false" extends `${infer T extends "false" | false}` ? T : never; // "false"
|
||||
>PStringLiteral09 : Symbol(PStringLiteral09, Decl(templateLiteralTypes4.ts, 132, 86))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 133, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 133, 48))
|
||||
|
||||
type PStringLiteral10 = "undefined" extends `${infer T extends "undefined" | undefined}` ? T : never; // "undefined"
|
||||
>PStringLiteral10 : Symbol(PStringLiteral10, Decl(templateLiteralTypes4.ts, 133, 89))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 134, 52))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 134, 52))
|
||||
|
||||
type PStringLiteral11 = "null" extends `${infer T extends "null" | null}` ? T : never; // "null"
|
||||
>PStringLiteral11 : Symbol(PStringLiteral11, Decl(templateLiteralTypes4.ts, 134, 101))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 135, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 135, 47))
|
||||
|
||||
// #endregion string-literal
|
||||
|
||||
// #region string-literal-enum
|
||||
// string-literal-enum > number
|
||||
type PStringLiteralEnum00 = "0" extends `${infer T extends StringLiteralEnum | number}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum00 : Symbol(PStringLiteralEnum00, Decl(templateLiteralTypes4.ts, 135, 86))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 140, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 140, 48))
|
||||
|
||||
// string-literal-enum > enum
|
||||
type PStringLiteralEnum01 = "0" extends `${infer T extends StringLiteralEnum | NonLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum01 : Symbol(PStringLiteralEnum01, Decl(templateLiteralTypes4.ts, 140, 100))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 143, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 143, 48))
|
||||
|
||||
// string-literal-enum > (number-literal | number-literal-enum)
|
||||
type PStringLiteralEnum02 = "0" extends `${infer T extends StringLiteralEnum | 0}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum02 : Symbol(PStringLiteralEnum02, Decl(templateLiteralTypes4.ts, 143, 108))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 146, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 146, 48))
|
||||
|
||||
type PStringLiteralEnum03 = "0" extends `${infer T extends StringLiteralEnum | NumberLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum03 : Symbol(PStringLiteralEnum03, Decl(templateLiteralTypes4.ts, 146, 95))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 147, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 147, 48))
|
||||
|
||||
// string-literal-enum > bigint
|
||||
type PStringLiteralEnum04 = "0" extends `${infer T extends StringLiteralEnum | bigint}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum04 : Symbol(PStringLiteralEnum04, Decl(templateLiteralTypes4.ts, 147, 111))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 150, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 150, 48))
|
||||
|
||||
// string-literal-enum > bigint-literal
|
||||
type PStringLiteralEnum05 = "0" extends `${infer T extends StringLiteralEnum | 0n}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum05 : Symbol(PStringLiteralEnum05, Decl(templateLiteralTypes4.ts, 150, 100))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 153, 48))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 153, 48))
|
||||
|
||||
// string-literal-enum > boolean
|
||||
type PStringLiteralEnum06 = "true" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.True
|
||||
>PStringLiteralEnum06 : Symbol(PStringLiteralEnum06, Decl(templateLiteralTypes4.ts, 153, 96))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 156, 51))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 156, 51))
|
||||
|
||||
type PStringLiteralEnum07 = "false" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.False
|
||||
>PStringLiteralEnum07 : Symbol(PStringLiteralEnum07, Decl(templateLiteralTypes4.ts, 156, 104))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 157, 52))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 157, 52))
|
||||
|
||||
// string-literal-enum > (boolean-literal | undefined | null)
|
||||
type PStringLiteralEnum08 = "true" extends `${infer T extends StringLiteralEnum | true}` ? T : never; // StringLiteralEnum.True
|
||||
>PStringLiteralEnum08 : Symbol(PStringLiteralEnum08, Decl(templateLiteralTypes4.ts, 157, 105))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 160, 51))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 160, 51))
|
||||
|
||||
type PStringLiteralEnum09 = "false" extends `${infer T extends StringLiteralEnum | false}` ? T : never; // StringLiteralEnum.False
|
||||
>PStringLiteralEnum09 : Symbol(PStringLiteralEnum09, Decl(templateLiteralTypes4.ts, 160, 101))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 161, 52))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 161, 52))
|
||||
|
||||
type PStringLiteralEnum10 = "undefined" extends `${infer T extends StringLiteralEnum | undefined}` ? T : never; // StringLiteralEnum.Undefined
|
||||
>PStringLiteralEnum10 : Symbol(PStringLiteralEnum10, Decl(templateLiteralTypes4.ts, 161, 103))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 162, 56))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 162, 56))
|
||||
|
||||
type PStringLiteralEnum11 = "null" extends `${infer T extends StringLiteralEnum | null}` ? T : never; // StringLiteralEnum.Null
|
||||
>PStringLiteralEnum11 : Symbol(PStringLiteralEnum11, Decl(templateLiteralTypes4.ts, 162, 111))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 163, 51))
|
||||
>StringLiteralEnum : Symbol(StringLiteralEnum, Decl(templateLiteralTypes4.ts, 32, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 163, 51))
|
||||
|
||||
// #endregion string-literal-enum
|
||||
|
||||
// #region number
|
||||
// number > enum
|
||||
type PNumber0 = "0" extends `${infer T extends number | NonLiteralEnum}` ? T : never; // 0
|
||||
>PNumber0 : Symbol(PNumber0, Decl(templateLiteralTypes4.ts, 163, 101))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 168, 36))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 168, 36))
|
||||
|
||||
// number > number-literal-enum
|
||||
type PNumber1 = "0" extends `${infer T extends number | NumberLiteralEnum}` ? T : never; // 0
|
||||
>PNumber1 : Symbol(PNumber1, Decl(templateLiteralTypes4.ts, 168, 85))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 171, 36))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 171, 36))
|
||||
|
||||
// number > bigint
|
||||
type PNumber2 = "0" extends `${infer T extends number | bigint}` ? T : never; // 0
|
||||
>PNumber2 : Symbol(PNumber2, Decl(templateLiteralTypes4.ts, 171, 88))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 174, 36))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 174, 36))
|
||||
|
||||
// number > bigint-literal
|
||||
type PNumber3 = "0" extends `${infer T extends number | 0n}` ? T : never; // 0
|
||||
>PNumber3 : Symbol(PNumber3, Decl(templateLiteralTypes4.ts, 174, 77))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 177, 36))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 177, 36))
|
||||
|
||||
// #endregion number
|
||||
|
||||
// #region enum
|
||||
// enum > number-literal-enum
|
||||
type PEnum0 = "0" extends `${infer T extends NonLiteralEnum | NumberLiteralEnum}` ? T : never; // 0
|
||||
>PEnum0 : Symbol(PEnum0, Decl(templateLiteralTypes4.ts, 177, 73))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 182, 34))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 182, 34))
|
||||
|
||||
// enum > bigint
|
||||
type PEnum1 = "0" extends `${infer T extends NonLiteralEnum | bigint}` ? T : never; // 0
|
||||
>PEnum1 : Symbol(PEnum1, Decl(templateLiteralTypes4.ts, 182, 94))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 185, 34))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 185, 34))
|
||||
|
||||
// enum > bigint-literal
|
||||
type PEnum2 = "0" extends `${infer T extends NonLiteralEnum | 0n}` ? T : never; // 0
|
||||
>PEnum2 : Symbol(PEnum2, Decl(templateLiteralTypes4.ts, 185, 83))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 188, 34))
|
||||
>NonLiteralEnum : Symbol(NonLiteralEnum, Decl(templateLiteralTypes4.ts, 39, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 188, 34))
|
||||
|
||||
// #endregion enum
|
||||
|
||||
// #region number-literal
|
||||
// number-literal > bigint
|
||||
type PNumberLiteral0 = "0" extends `${infer T extends 0 | bigint}` ? T : never; // 0
|
||||
>PNumberLiteral0 : Symbol(PNumberLiteral0, Decl(templateLiteralTypes4.ts, 188, 79))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 193, 43))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 193, 43))
|
||||
|
||||
// number-literal > bigint-literal
|
||||
type PNumberLiteral1 = "0" extends `${infer T extends 0 | 0n}` ? T : never; // 0
|
||||
>PNumberLiteral1 : Symbol(PNumberLiteral1, Decl(templateLiteralTypes4.ts, 193, 79))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 196, 43))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 196, 43))
|
||||
|
||||
// #endregion number-literal
|
||||
|
||||
// #region number-literal-enum
|
||||
// number-literal-enum > bigint
|
||||
type PNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum | bigint}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>PNumberLiteralEnum0 : Symbol(PNumberLiteralEnum0, Decl(templateLiteralTypes4.ts, 196, 75))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 201, 47))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 201, 47))
|
||||
|
||||
// number-literal-enum > bigint-literal
|
||||
type PNumberLiteralEnum1 = "0" extends `${infer T extends NumberLiteralEnum | 0n}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>PNumberLiteralEnum1 : Symbol(PNumberLiteralEnum1, Decl(templateLiteralTypes4.ts, 201, 99))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 204, 47))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 204, 47))
|
||||
|
||||
// #endregion number-literal-enum
|
||||
|
||||
// non-matchable constituents are excluded
|
||||
type PExclude0 = "0" extends `${infer T extends "1" | number}` ? T : never; // 0
|
||||
>PExclude0 : Symbol(PExclude0, Decl(templateLiteralTypes4.ts, 204, 95))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 208, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 208, 37))
|
||||
|
||||
type PExclude1 = "0" extends `${infer T extends `1${string}` | number}` ? T : never; // 0
|
||||
>PExclude1 : Symbol(PExclude1, Decl(templateLiteralTypes4.ts, 208, 75))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 209, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 209, 37))
|
||||
|
||||
type PExclude2 = "0" extends `${infer T extends 1 | bigint}` ? T : never; // 0n
|
||||
>PExclude2 : Symbol(PExclude2, Decl(templateLiteralTypes4.ts, 209, 84))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 210, 37))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 210, 37))
|
||||
|
||||
type PExclude3 = "0" extends `${infer T extends NumberLiteralEnum.One | bigint}` ? T : never; // 0n
|
||||
>PExclude3 : Symbol(PExclude3, Decl(templateLiteralTypes4.ts, 210, 73))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 211, 37))
|
||||
>NumberLiteralEnum : Symbol(NumberLiteralEnum, Decl(templateLiteralTypes4.ts, 36, 90))
|
||||
>One : Symbol(NumberLiteralEnum.One, Decl(templateLiteralTypes4.ts, 38, 36))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 211, 37))
|
||||
|
||||
type PExclude4 = "100000000000000000000000" extends `${infer T extends number | bigint}` ? T : never; // 100000000000000000000000n
|
||||
>PExclude4 : Symbol(PExclude4, Decl(templateLiteralTypes4.ts, 211, 93))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 212, 60))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 212, 60))
|
||||
|
||||
// infer to prefix from string
|
||||
type TPrefix0 = "100" extends `${infer T extends number}${string}` ? T : never; // 1
|
||||
>TPrefix0 : Symbol(TPrefix0, Decl(templateLiteralTypes4.ts, 212, 101))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 215, 38))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 215, 38))
|
||||
|
||||
type TPrefix1 = "trueabc" extends `${infer T extends boolean}${string}` ? T : never; // boolean (T only receives 't', not the whole string)
|
||||
>TPrefix1 : Symbol(TPrefix1, Decl(templateLiteralTypes4.ts, 215, 79))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 216, 42))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 216, 42))
|
||||
|
||||
type TPrefix2 = `100:${string}` extends `${infer T extends number}:${string}` ? T : never; // 100 (T receives '100' because it scans until ':')
|
||||
>TPrefix2 : Symbol(TPrefix2, Decl(templateLiteralTypes4.ts, 216, 84))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 217, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 217, 48))
|
||||
|
||||
// can use union w/multiple branches to extract each possibility
|
||||
type ExtractPrimitives<T extends string> =
|
||||
>ExtractPrimitives : Symbol(ExtractPrimitives, Decl(templateLiteralTypes4.ts, 217, 90))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 220, 23))
|
||||
|
||||
| T
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 220, 23))
|
||||
|
||||
| (T extends `${infer U extends number}` ? U : never)
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 220, 23))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 222, 25))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 222, 25))
|
||||
|
||||
| (T extends `${infer U extends bigint}` ? U : never)
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 220, 23))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 223, 25))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 223, 25))
|
||||
|
||||
| (T extends `${infer U extends boolean | null | undefined}` ? U : never)
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 220, 23))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 224, 25))
|
||||
>U : Symbol(U, Decl(templateLiteralTypes4.ts, 224, 25))
|
||||
|
||||
;
|
||||
|
||||
type TExtract0 = ExtractPrimitives<"100">; // "100" | 100 | 100n
|
||||
>TExtract0 : Symbol(TExtract0, Decl(templateLiteralTypes4.ts, 225, 5))
|
||||
>ExtractPrimitives : Symbol(ExtractPrimitives, Decl(templateLiteralTypes4.ts, 217, 90))
|
||||
|
||||
type TExtract1 = ExtractPrimitives<"1.1">; // "1.1" | 1.1
|
||||
>TExtract1 : Symbol(TExtract1, Decl(templateLiteralTypes4.ts, 227, 42))
|
||||
>ExtractPrimitives : Symbol(ExtractPrimitives, Decl(templateLiteralTypes4.ts, 217, 90))
|
||||
|
||||
type TExtract2 = ExtractPrimitives<"true">; // "true" | true
|
||||
>TExtract2 : Symbol(TExtract2, Decl(templateLiteralTypes4.ts, 228, 42))
|
||||
>ExtractPrimitives : Symbol(ExtractPrimitives, Decl(templateLiteralTypes4.ts, 217, 90))
|
||||
|
||||
|
||||
|
||||
// example use case (based on old TypedObjects proposal):
|
||||
|
||||
// Use constrained `infer` in template literal to get ordinal indices as numbers:
|
||||
type IndexFor<S extends string> = S extends `${infer N extends number}` ? N : never;
|
||||
>IndexFor : Symbol(IndexFor, Decl(templateLiteralTypes4.ts, 229, 43))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes4.ts, 236, 14))
|
||||
>S : Symbol(S, Decl(templateLiteralTypes4.ts, 236, 14))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 236, 52))
|
||||
>N : Symbol(N, Decl(templateLiteralTypes4.ts, 236, 52))
|
||||
|
||||
type IndicesOf<T> = IndexFor<Extract<keyof T, string>>; // ordinal indices as number literals
|
||||
>IndicesOf : Symbol(IndicesOf, Decl(templateLiteralTypes4.ts, 236, 84))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 237, 15))
|
||||
>IndexFor : Symbol(IndexFor, Decl(templateLiteralTypes4.ts, 229, 43))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 237, 15))
|
||||
|
||||
interface FieldDefinition {
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
readonly name: string;
|
||||
>name : Symbol(FieldDefinition.name, Decl(templateLiteralTypes4.ts, 239, 27))
|
||||
|
||||
readonly type: "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64";
|
||||
>type : Symbol(FieldDefinition.type, Decl(templateLiteralTypes4.ts, 240, 26))
|
||||
}
|
||||
|
||||
type FieldType<T extends FieldDefinition["type"]> =
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 244, 15))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
T extends "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64" ? number :
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 244, 15))
|
||||
|
||||
T extends "f32" | "f64" ? bigint :
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 244, 15))
|
||||
|
||||
never;
|
||||
|
||||
// Generates named members like `{ x: number, y: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectNamedMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
>TypedObjectNamedMembers : Symbol(TypedObjectNamedMembers, Decl(templateLiteralTypes4.ts, 247, 10))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 250, 29))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
[P in TDef[number]["name"]]: FieldType<Extract<TDef[number], { readonly name: P }>["type"]>;
|
||||
>P : Symbol(P, Decl(templateLiteralTypes4.ts, 251, 5))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 250, 29))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 250, 29))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes4.ts, 251, 66))
|
||||
>P : Symbol(P, Decl(templateLiteralTypes4.ts, 251, 5))
|
||||
|
||||
};
|
||||
|
||||
// Generates ordinal members like `{ 0: number, 1: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectOrdinalMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
>TypedObjectOrdinalMembers : Symbol(TypedObjectOrdinalMembers, Decl(templateLiteralTypes4.ts, 252, 2))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 255, 31))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
[I in Extract<keyof TDef, `${number}`>]: FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 256, 5))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 255, 31))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 255, 31))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 256, 5))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
};
|
||||
|
||||
// Default members
|
||||
interface TypedObjectMembers<TDef extends readonly FieldDefinition[]> {
|
||||
>TypedObjectMembers : Symbol(TypedObjectMembers, Decl(templateLiteralTypes4.ts, 257, 2))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
// get/set a field by name
|
||||
get<K extends TDef[number]["name"]>(key: K): FieldType<Extract<TDef[number], { readonly name: K }>["type"]>;
|
||||
>get : Symbol(TypedObjectMembers.get, Decl(templateLiteralTypes4.ts, 260, 71))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 262, 8))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>key : Symbol(key, Decl(templateLiteralTypes4.ts, 262, 40))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 262, 8))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes4.ts, 262, 82))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 262, 8))
|
||||
|
||||
set<K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], { readonly name: K }>["type"]>): void;
|
||||
>set : Symbol(TypedObjectMembers.set, Decl(templateLiteralTypes4.ts, 262, 112))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 263, 8))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>key : Symbol(key, Decl(templateLiteralTypes4.ts, 263, 40))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 263, 8))
|
||||
>value : Symbol(value, Decl(templateLiteralTypes4.ts, 263, 47))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>name : Symbol(name, Decl(templateLiteralTypes4.ts, 263, 88))
|
||||
>K : Symbol(K, Decl(templateLiteralTypes4.ts, 263, 8))
|
||||
|
||||
// get/set a field by index
|
||||
getIndex<I extends IndicesOf<TDef>>(index: I): FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
>getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 266, 13))
|
||||
>IndicesOf : Symbol(IndicesOf, Decl(templateLiteralTypes4.ts, 236, 84))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>index : Symbol(index, Decl(templateLiteralTypes4.ts, 266, 40))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 266, 13))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 266, 13))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
setIndex<I extends IndicesOf<TDef>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>): void;
|
||||
>setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 267, 13))
|
||||
>IndicesOf : Symbol(IndicesOf, Decl(templateLiteralTypes4.ts, 236, 84))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>index : Symbol(index, Decl(templateLiteralTypes4.ts, 267, 40))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 267, 13))
|
||||
>value : Symbol(value, Decl(templateLiteralTypes4.ts, 267, 49))
|
||||
>FieldType : Symbol(FieldType, Decl(templateLiteralTypes4.ts, 242, 1))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 260, 29))
|
||||
>I : Symbol(I, Decl(templateLiteralTypes4.ts, 267, 13))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
}
|
||||
|
||||
type TypedObject<TDef extends readonly FieldDefinition[]> =
|
||||
>TypedObject : Symbol(TypedObject, Decl(templateLiteralTypes4.ts, 268, 1))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 270, 17))
|
||||
>FieldDefinition : Symbol(FieldDefinition, Decl(templateLiteralTypes4.ts, 237, 55))
|
||||
|
||||
& TypedObjectMembers<TDef>
|
||||
>TypedObjectMembers : Symbol(TypedObjectMembers, Decl(templateLiteralTypes4.ts, 257, 2))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 270, 17))
|
||||
|
||||
& TypedObjectNamedMembers<TDef>
|
||||
>TypedObjectNamedMembers : Symbol(TypedObjectNamedMembers, Decl(templateLiteralTypes4.ts, 247, 10))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 270, 17))
|
||||
|
||||
& TypedObjectOrdinalMembers<TDef>;
|
||||
>TypedObjectOrdinalMembers : Symbol(TypedObjectOrdinalMembers, Decl(templateLiteralTypes4.ts, 252, 2))
|
||||
>TDef : Symbol(TDef, Decl(templateLiteralTypes4.ts, 270, 17))
|
||||
|
||||
// NOTE: type would normally be created from something like `const Point = TypedObject([...])` from which we would infer the type
|
||||
type Point = TypedObject<[
|
||||
>Point : Symbol(Point, Decl(templateLiteralTypes4.ts, 273, 38))
|
||||
>TypedObject : Symbol(TypedObject, Decl(templateLiteralTypes4.ts, 268, 1))
|
||||
|
||||
{ name: "x", type: "f64" },
|
||||
>name : Symbol(name, Decl(templateLiteralTypes4.ts, 277, 5))
|
||||
>type : Symbol(type, Decl(templateLiteralTypes4.ts, 277, 16))
|
||||
|
||||
{ name: "y", type: "f64" },
|
||||
>name : Symbol(name, Decl(templateLiteralTypes4.ts, 278, 5))
|
||||
>type : Symbol(type, Decl(templateLiteralTypes4.ts, 278, 16))
|
||||
|
||||
]>;
|
||||
|
||||
declare const p: Point;
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>Point : Symbol(Point, Decl(templateLiteralTypes4.ts, 273, 38))
|
||||
|
||||
p.getIndex(0); // ok, 0 is a valid index
|
||||
>p.getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
|
||||
p.getIndex(1); // ok, 1 is a valid index
|
||||
>p.getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
|
||||
p.getIndex(2); // error, 2 is not a valid index
|
||||
>p.getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>getIndex : Symbol(TypedObjectMembers.getIndex, Decl(templateLiteralTypes4.ts, 263, 125))
|
||||
|
||||
p.setIndex(0, 0); // ok, 0 is a valid index
|
||||
>p.setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
|
||||
p.setIndex(1, 0); // ok, 1 is a valid index
|
||||
>p.setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
|
||||
p.setIndex(2, 3); // error, 2 is not a valid index
|
||||
>p.setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
>p : Symbol(p, Decl(templateLiteralTypes4.ts, 281, 13))
|
||||
>setIndex : Symbol(TypedObjectMembers.setIndex, Decl(templateLiteralTypes4.ts, 266, 104))
|
||||
|
||||
// function inference
|
||||
declare function f1<T extends string | number>(s: `**${T}**`): T;
|
||||
>f1 : Symbol(f1, Decl(templateLiteralTypes4.ts, 288, 17))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 291, 20))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes4.ts, 291, 47))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 291, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 291, 20))
|
||||
|
||||
f1("**123**"); // "123"
|
||||
>f1 : Symbol(f1, Decl(templateLiteralTypes4.ts, 288, 17))
|
||||
|
||||
declare function f2<T extends number>(s: `**${T}**`): T;
|
||||
>f2 : Symbol(f2, Decl(templateLiteralTypes4.ts, 292, 14))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 294, 20))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes4.ts, 294, 38))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 294, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 294, 20))
|
||||
|
||||
f2("**123**"); // 123
|
||||
>f2 : Symbol(f2, Decl(templateLiteralTypes4.ts, 292, 14))
|
||||
|
||||
declare function f3<T extends bigint>(s: `**${T}**`): T;
|
||||
>f3 : Symbol(f3, Decl(templateLiteralTypes4.ts, 295, 14))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 297, 20))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes4.ts, 297, 38))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 297, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 297, 20))
|
||||
|
||||
f3("**123**"); // 123n
|
||||
>f3 : Symbol(f3, Decl(templateLiteralTypes4.ts, 295, 14))
|
||||
|
||||
declare function f4<T extends boolean>(s: `**${T}**`): T;
|
||||
>f4 : Symbol(f4, Decl(templateLiteralTypes4.ts, 298, 14))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 300, 20))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes4.ts, 300, 39))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 300, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes4.ts, 300, 20))
|
||||
|
||||
f4("**true**"); // true | "true"
|
||||
>f4 : Symbol(f4, Decl(templateLiteralTypes4.ts, 298, 14))
|
||||
|
||||
f4("**false**"); // false | "false"
|
||||
>f4 : Symbol(f4, Decl(templateLiteralTypes4.ts, 298, 14))
|
||||
|
||||
@@ -0,0 +1,608 @@
|
||||
=== tests/cases/conformance/types/literal/templateLiteralTypes4.ts ===
|
||||
// infer from number
|
||||
type TNumber0 = "100" extends `${infer N extends number}` ? N : never; // 100
|
||||
>TNumber0 : 100
|
||||
|
||||
type TNumber1 = "-100" extends `${infer N extends number}` ? N : never; // -100
|
||||
>TNumber1 : -100
|
||||
|
||||
type TNumber2 = "1.1" extends `${infer N extends number}` ? N : never; // 1.1
|
||||
>TNumber2 : 1.1
|
||||
|
||||
type TNumber3 = "8e-11" extends `${infer N extends number}` ? N : never; // 8e-11 (0.00000000008)
|
||||
>TNumber3 : 8e-11
|
||||
|
||||
type TNumber4 = "0x10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber4 : number
|
||||
|
||||
type TNumber5 = "0o10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber5 : number
|
||||
|
||||
type TNumber6 = "0b10" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber6 : number
|
||||
|
||||
type TNumber7 = "10e2" extends `${infer N extends number}` ? N : never; // number (not round-trippable)
|
||||
>TNumber7 : number
|
||||
|
||||
type TNumber8 = "abcd" extends `${infer N extends number}` ? N : never; // never
|
||||
>TNumber8 : never
|
||||
|
||||
// infer from bigint
|
||||
type TBigInt0 = "100" extends `${infer N extends bigint}` ? N : never; // 100n
|
||||
>TBigInt0 : 100n
|
||||
|
||||
type TBigInt1 = "-100" extends `${infer N extends bigint}` ? N : never; // -100n
|
||||
>TBigInt1 : -100n
|
||||
|
||||
type TBigInt2 = "0x10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt2 : bigint
|
||||
|
||||
type TBigInt3 = "0o10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt3 : bigint
|
||||
|
||||
type TBigInt4 = "0b10" extends `${infer N extends bigint}` ? N : never; // bigint (not round-trippable)
|
||||
>TBigInt4 : bigint
|
||||
|
||||
type TBigInt5 = "1.1" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt5 : never
|
||||
|
||||
type TBigInt6 = "10e2" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt6 : never
|
||||
|
||||
type TBigInt7 = "abcd" extends `${infer N extends bigint}` ? N : never; // never
|
||||
>TBigInt7 : never
|
||||
|
||||
// infer from boolean
|
||||
type TBoolean0 = "true" extends `${infer T extends boolean}` ? T : never; // true
|
||||
>TBoolean0 : true
|
||||
|
||||
type TBoolean1 = "false" extends `${infer T extends boolean}` ? T : never; // false
|
||||
>TBoolean1 : false
|
||||
|
||||
type TBoolean2 = "abcd" extends `${infer T extends boolean}` ? T : never; // never
|
||||
>TBoolean2 : never
|
||||
|
||||
// infer from null
|
||||
type TNull0 = "null" extends `${infer T extends null}` ? T : never; // null
|
||||
>TNull0 : null
|
||||
>null : null
|
||||
|
||||
type TNull1 = "abcd" extends `${infer T extends null}` ? T : never; // never
|
||||
>TNull1 : never
|
||||
>null : null
|
||||
|
||||
// infer from undefined
|
||||
type TUndefined0 = "undefined" extends `${infer T extends undefined}` ? T : never; // undefined
|
||||
>TUndefined0 : undefined
|
||||
|
||||
type TUndefined1 = "abcd" extends `${infer T extends undefined}` ? T : never; // never
|
||||
>TUndefined1 : never
|
||||
|
||||
// infer from literal enums
|
||||
const enum StringLiteralEnum { Zero = "0", True = "true", False = "false", Undefined = "undefined", Null = "null" }
|
||||
>StringLiteralEnum : StringLiteralEnum
|
||||
>Zero : StringLiteralEnum.Zero
|
||||
>"0" : "0"
|
||||
>True : StringLiteralEnum.True
|
||||
>"true" : "true"
|
||||
>False : StringLiteralEnum.False
|
||||
>"false" : "false"
|
||||
>Undefined : StringLiteralEnum.Undefined
|
||||
>"undefined" : "undefined"
|
||||
>Null : StringLiteralEnum.Null
|
||||
>"null" : "null"
|
||||
|
||||
type TStringLiteralEnum0 = "0" extends `${infer T extends StringLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>TStringLiteralEnum0 : StringLiteralEnum.Zero
|
||||
|
||||
const enum NumberLiteralEnum { Zero, One }
|
||||
>NumberLiteralEnum : NumberLiteralEnum
|
||||
>Zero : NumberLiteralEnum.Zero
|
||||
>One : NumberLiteralEnum.One
|
||||
|
||||
type TNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>TNumberLiteralEnum0 : NumberLiteralEnum.Zero
|
||||
|
||||
// infer from non-literal enums
|
||||
const enum NonLiteralEnum { Zero = NumberLiteralEnum.Zero, One = NumberLiteralEnum.One }
|
||||
>NonLiteralEnum : NonLiteralEnum
|
||||
>Zero : NonLiteralEnum
|
||||
>NumberLiteralEnum.Zero : NumberLiteralEnum.Zero
|
||||
>NumberLiteralEnum : typeof NumberLiteralEnum
|
||||
>Zero : NumberLiteralEnum.Zero
|
||||
>One : NonLiteralEnum
|
||||
>NumberLiteralEnum.One : NumberLiteralEnum.One
|
||||
>NumberLiteralEnum : typeof NumberLiteralEnum
|
||||
>One : NumberLiteralEnum.One
|
||||
|
||||
type TNonLiteralEnum0 = "0" extends `${infer T extends NonLiteralEnum}` ? T : never; // 0
|
||||
>TNonLiteralEnum0 : 0
|
||||
|
||||
// infer using priority:
|
||||
// string > template-literal > (string-literal | string-literal-enum) >
|
||||
// number > enum > (number-literal | number-literal-enum) >
|
||||
// bigint > bigint-literal >
|
||||
// boolean > (boolean-literal | undefined | null)
|
||||
|
||||
// #region string
|
||||
// string > string-literal-enum
|
||||
type PString00 = "0" extends `${infer T extends string | StringLiteralEnum}` ? T : never; // "0"
|
||||
>PString00 : "0"
|
||||
|
||||
// string > number
|
||||
type PString01 = "0" extends `${infer T extends string | number}` ? T : never; // "0"
|
||||
>PString01 : "0"
|
||||
|
||||
// string > enum
|
||||
type PString02 = "0" extends `${infer T extends string | NonLiteralEnum}` ? T : never; // "0"
|
||||
>PString02 : "0"
|
||||
|
||||
// string > (number-literal | number-literal-enum)
|
||||
type PString03 = "0" extends `${infer T extends string | 0}` ? T : never; // "0"
|
||||
>PString03 : "0"
|
||||
|
||||
type PString04 = "0" extends `${infer T extends string | NumberLiteralEnum}` ? T : never; // "0"
|
||||
>PString04 : "0"
|
||||
|
||||
// string > bigint
|
||||
type PString05 = "0" extends `${infer T extends string | bigint}` ? T : never; // "0"
|
||||
>PString05 : "0"
|
||||
|
||||
// string > bigint-literal
|
||||
type PString06 = "0" extends `${infer T extends string | 0n}` ? T : never; // "0"
|
||||
>PString06 : "0"
|
||||
|
||||
// string > boolean
|
||||
type PString07 = "true" extends `${infer T extends string | boolean}` ? T : never; // "true"
|
||||
>PString07 : "true"
|
||||
|
||||
type PString08 = "false" extends `${infer T extends string | boolean}` ? T : never; // "false"
|
||||
>PString08 : "false"
|
||||
|
||||
// string > (boolean-literal | undefined | null)
|
||||
type PString09 = "true" extends `${infer T extends string | true}` ? T : never; // "true"
|
||||
>PString09 : "true"
|
||||
>true : true
|
||||
|
||||
type PString10 = "false" extends `${infer T extends string | false}` ? T : never; // "false"
|
||||
>PString10 : "false"
|
||||
>false : false
|
||||
|
||||
type PString11 = "undefined" extends `${infer T extends string | undefined}` ? T : never; // "undefined"
|
||||
>PString11 : "undefined"
|
||||
|
||||
type PString12 = "null" extends `${infer T extends string | null}` ? T : never; // "null"
|
||||
>PString12 : "null"
|
||||
>null : null
|
||||
|
||||
// #endregion string
|
||||
|
||||
// #region template-literal
|
||||
// template-literal > number
|
||||
type PTemplate00 = "10" extends `${infer T extends `1${string}` | number}` ? T : never; // "10"
|
||||
>PTemplate00 : "10"
|
||||
|
||||
// template-literal > enum
|
||||
type PTemplate01 = "10" extends `${infer T extends `1${string}` | NonLiteralEnum}` ? T : never; // "10"
|
||||
>PTemplate01 : "10"
|
||||
|
||||
// template-literal > (number-literal | number-literal-enum)
|
||||
type PTemplate02 = "10" extends `${infer T extends `1${string}` | 10}` ? T : never; // "10"
|
||||
>PTemplate02 : "10"
|
||||
|
||||
type PTemplate03 = "10" extends `${infer T extends `1${string}` | NumberLiteralEnum}` ? T : never; // "10"
|
||||
>PTemplate03 : "10"
|
||||
|
||||
// template-literal > bigint
|
||||
type PTemplate04 = "10" extends `${infer T extends `1${string}` | bigint}` ? T : never; // "10"
|
||||
>PTemplate04 : "10"
|
||||
|
||||
// template-literal > bigint-literal
|
||||
type PTemplate05 = "10" extends `${infer T extends `1${string}` | 10n}` ? T : never; // "10"
|
||||
>PTemplate05 : "10"
|
||||
|
||||
// template-literal > boolean
|
||||
type PTemplate06 = "true" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "true"
|
||||
>PTemplate06 : "true"
|
||||
|
||||
type PTemplate07 = "false" extends `${infer T extends `${string}e` | boolean}` ? T : never; // "false"
|
||||
>PTemplate07 : "false"
|
||||
|
||||
// template-literal > (boolean-literal | undefined | null)
|
||||
type PTemplate08 = "true" extends `${infer T extends `${"t"}${string}` | true}` ? T : never; // "true"
|
||||
>PTemplate08 : "true"
|
||||
>true : true
|
||||
|
||||
type PTemplate09 = "false" extends `${infer T extends `${"f"}${string}` | false}` ? T : never; // "false"
|
||||
>PTemplate09 : "false"
|
||||
>false : false
|
||||
|
||||
type PTemplate10 = "undefined" extends `${infer T extends `${"u"}${string}` | undefined}` ? T : never; // "undefined"
|
||||
>PTemplate10 : "undefined"
|
||||
|
||||
type PTemplate11 = "null" extends `${infer T extends `${"n"}${string}` | null}` ? T : never; // "null"
|
||||
>PTemplate11 : "null"
|
||||
>null : null
|
||||
|
||||
// #endregion template-literal
|
||||
|
||||
// #region string-literal
|
||||
// string-literal > number
|
||||
type PStringLiteral00 = "0" extends `${infer T extends "0" | number}` ? T : never; // "0"
|
||||
>PStringLiteral00 : "0"
|
||||
|
||||
// string-literal > enum
|
||||
type PStringLiteral01 = "0" extends `${infer T extends "0" | NonLiteralEnum}` ? T : never; // "0"
|
||||
>PStringLiteral01 : "0"
|
||||
|
||||
// string-literal > (number-literal | number-literal-enum)
|
||||
type PStringLiteral02 = "0" extends `${infer T extends "0" | 0}` ? T : never; // "0"
|
||||
>PStringLiteral02 : "0"
|
||||
|
||||
type PStringLiteral03 = "0" extends `${infer T extends "0" | NumberLiteralEnum}` ? T : never; // "0"
|
||||
>PStringLiteral03 : "0"
|
||||
|
||||
// string-literal > bigint
|
||||
type PStringLiteral04 = "0" extends `${infer T extends "0" | bigint}` ? T : never; // "0"
|
||||
>PStringLiteral04 : "0"
|
||||
|
||||
// string-literal > bigint-literal
|
||||
type PStringLiteral05 = "0" extends `${infer T extends "0" | 0n}` ? T : never; // "0"
|
||||
>PStringLiteral05 : "0"
|
||||
|
||||
// string-literal > boolean
|
||||
type PStringLiteral06 = "true" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "true"
|
||||
>PStringLiteral06 : "true"
|
||||
|
||||
type PStringLiteral07 = "false" extends `${infer T extends "true" | "false" | boolean}` ? T : never; // "false"
|
||||
>PStringLiteral07 : "false"
|
||||
|
||||
// string-literal > (boolean-literal | undefined | null)
|
||||
type PStringLiteral08 = "true" extends `${infer T extends "true" | true}` ? T : never; // "true"
|
||||
>PStringLiteral08 : "true"
|
||||
>true : true
|
||||
|
||||
type PStringLiteral09 = "false" extends `${infer T extends "false" | false}` ? T : never; // "false"
|
||||
>PStringLiteral09 : "false"
|
||||
>false : false
|
||||
|
||||
type PStringLiteral10 = "undefined" extends `${infer T extends "undefined" | undefined}` ? T : never; // "undefined"
|
||||
>PStringLiteral10 : "undefined"
|
||||
|
||||
type PStringLiteral11 = "null" extends `${infer T extends "null" | null}` ? T : never; // "null"
|
||||
>PStringLiteral11 : "null"
|
||||
>null : null
|
||||
|
||||
// #endregion string-literal
|
||||
|
||||
// #region string-literal-enum
|
||||
// string-literal-enum > number
|
||||
type PStringLiteralEnum00 = "0" extends `${infer T extends StringLiteralEnum | number}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum00 : StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > enum
|
||||
type PStringLiteralEnum01 = "0" extends `${infer T extends StringLiteralEnum | NonLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum01 : StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > (number-literal | number-literal-enum)
|
||||
type PStringLiteralEnum02 = "0" extends `${infer T extends StringLiteralEnum | 0}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum02 : StringLiteralEnum.Zero
|
||||
|
||||
type PStringLiteralEnum03 = "0" extends `${infer T extends StringLiteralEnum | NumberLiteralEnum}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum03 : StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint
|
||||
type PStringLiteralEnum04 = "0" extends `${infer T extends StringLiteralEnum | bigint}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum04 : StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > bigint-literal
|
||||
type PStringLiteralEnum05 = "0" extends `${infer T extends StringLiteralEnum | 0n}` ? T : never; // StringLiteralEnum.Zero
|
||||
>PStringLiteralEnum05 : StringLiteralEnum.Zero
|
||||
|
||||
// string-literal-enum > boolean
|
||||
type PStringLiteralEnum06 = "true" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.True
|
||||
>PStringLiteralEnum06 : StringLiteralEnum.True
|
||||
|
||||
type PStringLiteralEnum07 = "false" extends `${infer T extends StringLiteralEnum | boolean}` ? T : never; // StringLiteralEnum.False
|
||||
>PStringLiteralEnum07 : StringLiteralEnum.False
|
||||
|
||||
// string-literal-enum > (boolean-literal | undefined | null)
|
||||
type PStringLiteralEnum08 = "true" extends `${infer T extends StringLiteralEnum | true}` ? T : never; // StringLiteralEnum.True
|
||||
>PStringLiteralEnum08 : StringLiteralEnum.True
|
||||
>true : true
|
||||
|
||||
type PStringLiteralEnum09 = "false" extends `${infer T extends StringLiteralEnum | false}` ? T : never; // StringLiteralEnum.False
|
||||
>PStringLiteralEnum09 : StringLiteralEnum.False
|
||||
>false : false
|
||||
|
||||
type PStringLiteralEnum10 = "undefined" extends `${infer T extends StringLiteralEnum | undefined}` ? T : never; // StringLiteralEnum.Undefined
|
||||
>PStringLiteralEnum10 : StringLiteralEnum.Undefined
|
||||
|
||||
type PStringLiteralEnum11 = "null" extends `${infer T extends StringLiteralEnum | null}` ? T : never; // StringLiteralEnum.Null
|
||||
>PStringLiteralEnum11 : StringLiteralEnum.Null
|
||||
>null : null
|
||||
|
||||
// #endregion string-literal-enum
|
||||
|
||||
// #region number
|
||||
// number > enum
|
||||
type PNumber0 = "0" extends `${infer T extends number | NonLiteralEnum}` ? T : never; // 0
|
||||
>PNumber0 : 0
|
||||
|
||||
// number > number-literal-enum
|
||||
type PNumber1 = "0" extends `${infer T extends number | NumberLiteralEnum}` ? T : never; // 0
|
||||
>PNumber1 : 0
|
||||
|
||||
// number > bigint
|
||||
type PNumber2 = "0" extends `${infer T extends number | bigint}` ? T : never; // 0
|
||||
>PNumber2 : 0
|
||||
|
||||
// number > bigint-literal
|
||||
type PNumber3 = "0" extends `${infer T extends number | 0n}` ? T : never; // 0
|
||||
>PNumber3 : 0
|
||||
|
||||
// #endregion number
|
||||
|
||||
// #region enum
|
||||
// enum > number-literal-enum
|
||||
type PEnum0 = "0" extends `${infer T extends NonLiteralEnum | NumberLiteralEnum}` ? T : never; // 0
|
||||
>PEnum0 : 0
|
||||
|
||||
// enum > bigint
|
||||
type PEnum1 = "0" extends `${infer T extends NonLiteralEnum | bigint}` ? T : never; // 0
|
||||
>PEnum1 : 0
|
||||
|
||||
// enum > bigint-literal
|
||||
type PEnum2 = "0" extends `${infer T extends NonLiteralEnum | 0n}` ? T : never; // 0
|
||||
>PEnum2 : 0
|
||||
|
||||
// #endregion enum
|
||||
|
||||
// #region number-literal
|
||||
// number-literal > bigint
|
||||
type PNumberLiteral0 = "0" extends `${infer T extends 0 | bigint}` ? T : never; // 0
|
||||
>PNumberLiteral0 : 0
|
||||
|
||||
// number-literal > bigint-literal
|
||||
type PNumberLiteral1 = "0" extends `${infer T extends 0 | 0n}` ? T : never; // 0
|
||||
>PNumberLiteral1 : 0
|
||||
|
||||
// #endregion number-literal
|
||||
|
||||
// #region number-literal-enum
|
||||
// number-literal-enum > bigint
|
||||
type PNumberLiteralEnum0 = "0" extends `${infer T extends NumberLiteralEnum | bigint}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>PNumberLiteralEnum0 : NumberLiteralEnum.Zero
|
||||
|
||||
// number-literal-enum > bigint-literal
|
||||
type PNumberLiteralEnum1 = "0" extends `${infer T extends NumberLiteralEnum | 0n}` ? T : never; // NumberLiteralEnum.Zero
|
||||
>PNumberLiteralEnum1 : NumberLiteralEnum.Zero
|
||||
|
||||
// #endregion number-literal-enum
|
||||
|
||||
// non-matchable constituents are excluded
|
||||
type PExclude0 = "0" extends `${infer T extends "1" | number}` ? T : never; // 0
|
||||
>PExclude0 : 0
|
||||
|
||||
type PExclude1 = "0" extends `${infer T extends `1${string}` | number}` ? T : never; // 0
|
||||
>PExclude1 : 0
|
||||
|
||||
type PExclude2 = "0" extends `${infer T extends 1 | bigint}` ? T : never; // 0n
|
||||
>PExclude2 : 0n
|
||||
|
||||
type PExclude3 = "0" extends `${infer T extends NumberLiteralEnum.One | bigint}` ? T : never; // 0n
|
||||
>PExclude3 : 0n
|
||||
>NumberLiteralEnum : any
|
||||
|
||||
type PExclude4 = "100000000000000000000000" extends `${infer T extends number | bigint}` ? T : never; // 100000000000000000000000n
|
||||
>PExclude4 : 100000000000000000000000n
|
||||
|
||||
// infer to prefix from string
|
||||
type TPrefix0 = "100" extends `${infer T extends number}${string}` ? T : never; // 1
|
||||
>TPrefix0 : 1
|
||||
|
||||
type TPrefix1 = "trueabc" extends `${infer T extends boolean}${string}` ? T : never; // boolean (T only receives 't', not the whole string)
|
||||
>TPrefix1 : boolean
|
||||
|
||||
type TPrefix2 = `100:${string}` extends `${infer T extends number}:${string}` ? T : never; // 100 (T receives '100' because it scans until ':')
|
||||
>TPrefix2 : 100
|
||||
|
||||
// can use union w/multiple branches to extract each possibility
|
||||
type ExtractPrimitives<T extends string> =
|
||||
>ExtractPrimitives : ExtractPrimitives<T>
|
||||
|
||||
| T
|
||||
| (T extends `${infer U extends number}` ? U : never)
|
||||
| (T extends `${infer U extends bigint}` ? U : never)
|
||||
| (T extends `${infer U extends boolean | null | undefined}` ? U : never)
|
||||
>null : null
|
||||
|
||||
;
|
||||
|
||||
type TExtract0 = ExtractPrimitives<"100">; // "100" | 100 | 100n
|
||||
>TExtract0 : "100" | 100 | 100n
|
||||
|
||||
type TExtract1 = ExtractPrimitives<"1.1">; // "1.1" | 1.1
|
||||
>TExtract1 : "1.1" | 1.1
|
||||
|
||||
type TExtract2 = ExtractPrimitives<"true">; // "true" | true
|
||||
>TExtract2 : true | "true"
|
||||
|
||||
|
||||
|
||||
// example use case (based on old TypedObjects proposal):
|
||||
|
||||
// Use constrained `infer` in template literal to get ordinal indices as numbers:
|
||||
type IndexFor<S extends string> = S extends `${infer N extends number}` ? N : never;
|
||||
>IndexFor : IndexFor<S>
|
||||
|
||||
type IndicesOf<T> = IndexFor<Extract<keyof T, string>>; // ordinal indices as number literals
|
||||
>IndicesOf : IndicesOf<T>
|
||||
|
||||
interface FieldDefinition {
|
||||
readonly name: string;
|
||||
>name : string
|
||||
|
||||
readonly type: "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64";
|
||||
>type : "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" | "f32" | "f64"
|
||||
}
|
||||
|
||||
type FieldType<T extends FieldDefinition["type"]> =
|
||||
>FieldType : FieldType<T>
|
||||
|
||||
T extends "i8" | "i16" | "i32" | "u8" | "u16" | "u32" | "f32" | "f64" ? number :
|
||||
T extends "f32" | "f64" ? bigint :
|
||||
never;
|
||||
|
||||
// Generates named members like `{ x: number, y: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectNamedMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
>TypedObjectNamedMembers : TypedObjectNamedMembers<TDef>
|
||||
|
||||
[P in TDef[number]["name"]]: FieldType<Extract<TDef[number], { readonly name: P }>["type"]>;
|
||||
>name : P
|
||||
|
||||
};
|
||||
|
||||
// Generates ordinal members like `{ 0: number, 1: bigint }` from `[{ name: "x", type: "i32" }, { name: "y", type: "i64" }]`
|
||||
type TypedObjectOrdinalMembers<TDef extends readonly FieldDefinition[]> = {
|
||||
>TypedObjectOrdinalMembers : TypedObjectOrdinalMembers<TDef>
|
||||
|
||||
[I in Extract<keyof TDef, `${number}`>]: FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
};
|
||||
|
||||
// Default members
|
||||
interface TypedObjectMembers<TDef extends readonly FieldDefinition[]> {
|
||||
// get/set a field by name
|
||||
get<K extends TDef[number]["name"]>(key: K): FieldType<Extract<TDef[number], { readonly name: K }>["type"]>;
|
||||
>get : <K extends TDef[number]["name"]>(key: K) => FieldType<Extract<TDef[number], { readonly name: K;}>["type"]>
|
||||
>key : K
|
||||
>name : K
|
||||
|
||||
set<K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], { readonly name: K }>["type"]>): void;
|
||||
>set : <K extends TDef[number]["name"]>(key: K, value: FieldType<Extract<TDef[number], { readonly name: K;}>["type"]>) => void
|
||||
>key : K
|
||||
>value : FieldType<Extract<TDef[number], { readonly name: K; }>["type"]>
|
||||
>name : K
|
||||
|
||||
// get/set a field by index
|
||||
getIndex<I extends IndicesOf<TDef>>(index: I): FieldType<Extract<TDef[I], FieldDefinition>["type"]>;
|
||||
>getIndex : <I extends IndexFor<Extract<keyof TDef, string>>>(index: I) => FieldType<Extract<TDef[I], FieldDefinition>["type"]>
|
||||
>index : I
|
||||
|
||||
setIndex<I extends IndicesOf<TDef>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>): void;
|
||||
>setIndex : <I extends IndexFor<Extract<keyof TDef, string>>>(index: I, value: FieldType<Extract<TDef[I], FieldDefinition>["type"]>) => void
|
||||
>index : I
|
||||
>value : FieldType<Extract<TDef[I], FieldDefinition>["type"]>
|
||||
}
|
||||
|
||||
type TypedObject<TDef extends readonly FieldDefinition[]> =
|
||||
>TypedObject : TypedObject<TDef>
|
||||
|
||||
& TypedObjectMembers<TDef>
|
||||
& TypedObjectNamedMembers<TDef>
|
||||
& TypedObjectOrdinalMembers<TDef>;
|
||||
|
||||
// NOTE: type would normally be created from something like `const Point = TypedObject([...])` from which we would infer the type
|
||||
type Point = TypedObject<[
|
||||
>Point : TypedObjectMembers<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }]> & TypedObjectNamedMembers<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }]> & TypedObjectOrdinalMembers<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }]>
|
||||
|
||||
{ name: "x", type: "f64" },
|
||||
>name : "x"
|
||||
>type : "f64"
|
||||
|
||||
{ name: "y", type: "f64" },
|
||||
>name : "y"
|
||||
>type : "f64"
|
||||
|
||||
]>;
|
||||
|
||||
declare const p: Point;
|
||||
>p : Point
|
||||
|
||||
p.getIndex(0); // ok, 0 is a valid index
|
||||
>p.getIndex(0) : number
|
||||
>p.getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>p : Point
|
||||
>getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>0 : 0
|
||||
|
||||
p.getIndex(1); // ok, 1 is a valid index
|
||||
>p.getIndex(1) : number
|
||||
>p.getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>p : Point
|
||||
>getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>1 : 1
|
||||
|
||||
p.getIndex(2); // error, 2 is not a valid index
|
||||
>p.getIndex(2) : number
|
||||
>p.getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>p : Point
|
||||
>getIndex : <I extends 0 | 1>(index: I) => FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>
|
||||
>2 : 2
|
||||
|
||||
p.setIndex(0, 0); // ok, 0 is a valid index
|
||||
>p.setIndex(0, 0) : void
|
||||
>p.setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>p : Point
|
||||
>setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>0 : 0
|
||||
>0 : 0
|
||||
|
||||
p.setIndex(1, 0); // ok, 1 is a valid index
|
||||
>p.setIndex(1, 0) : void
|
||||
>p.setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>p : Point
|
||||
>setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
||||
p.setIndex(2, 3); // error, 2 is not a valid index
|
||||
>p.setIndex(2, 3) : void
|
||||
>p.setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>p : Point
|
||||
>setIndex : <I extends 0 | 1>(index: I, value: FieldType<Extract<[{ name: "x"; type: "f64"; }, { name: "y"; type: "f64"; }][I], FieldDefinition>["type"]>) => void
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
// function inference
|
||||
declare function f1<T extends string | number>(s: `**${T}**`): T;
|
||||
>f1 : <T extends string | number>(s: `**${T}**`) => T
|
||||
>s : `**${T}**`
|
||||
|
||||
f1("**123**"); // "123"
|
||||
>f1("**123**") : "123"
|
||||
>f1 : <T extends string | number>(s: `**${T}**`) => T
|
||||
>"**123**" : "**123**"
|
||||
|
||||
declare function f2<T extends number>(s: `**${T}**`): T;
|
||||
>f2 : <T extends number>(s: `**${T}**`) => T
|
||||
>s : `**${T}**`
|
||||
|
||||
f2("**123**"); // 123
|
||||
>f2("**123**") : 123
|
||||
>f2 : <T extends number>(s: `**${T}**`) => T
|
||||
>"**123**" : "**123**"
|
||||
|
||||
declare function f3<T extends bigint>(s: `**${T}**`): T;
|
||||
>f3 : <T extends bigint>(s: `**${T}**`) => T
|
||||
>s : `**${T}**`
|
||||
|
||||
f3("**123**"); // 123n
|
||||
>f3("**123**") : 123n
|
||||
>f3 : <T extends bigint>(s: `**${T}**`) => T
|
||||
>"**123**" : "**123**"
|
||||
|
||||
declare function f4<T extends boolean>(s: `**${T}**`): T;
|
||||
>f4 : <T extends boolean>(s: `**${T}**`) => T
|
||||
>s : `**${T}**`
|
||||
|
||||
f4("**true**"); // true | "true"
|
||||
>f4("**true**") : true
|
||||
>f4 : <T extends boolean>(s: `**${T}**`) => T
|
||||
>"**true**" : "**true**"
|
||||
|
||||
f4("**false**"); // false | "false"
|
||||
>f4("**false**") : false
|
||||
>f4 : <T extends boolean>(s: `**${T}**`) => T
|
||||
>"**false**" : "**false**"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user