mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-12 20:01:02 -05:00
Merge pull request #22323 from Microsoft/checkInferredConstraints
Check inferred constraints for 'infer X' type variables
This commit is contained in:
@@ -8261,28 +8261,18 @@ namespace ts {
|
||||
if (checkType === wildcardType || extendsType === wildcardType) {
|
||||
return wildcardType;
|
||||
}
|
||||
// If this is a distributive conditional type and the check type is generic, we need to defer
|
||||
// If this is a distributive conditional type and the check type is generic we need to defer
|
||||
// resolution of the conditional type such that a later instantiation will properly distribute
|
||||
// over union types.
|
||||
if (!root.isDistributive || !maybeTypeOfKind(checkType, TypeFlags.Instantiable)) {
|
||||
// Return falseType for a definitely false extends check. We check an instantations of the two
|
||||
// types with type parameters mapped to the wildcard type, the most permissive instantiations
|
||||
// possible (the wildcard type is assignable to and from all types). If those are not related,
|
||||
// then no instatiations will be and we can just return the false branch type.
|
||||
if (!isTypeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(extendsType))) {
|
||||
return instantiateType(root.falseType, mapper);
|
||||
}
|
||||
// The check could be true for some instantiation
|
||||
let combinedMapper: TypeMapper;
|
||||
if (root.inferTypeParameters) {
|
||||
const inferences = map(root.inferTypeParameters, createInferenceInfo);
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
// We don't want inferences from constraints as they may cause us to eagerly resolve the
|
||||
// conditional type instead of deferring resolution. Also, we always want strict function
|
||||
// types rules (i.e. proper contravariance) for inferences.
|
||||
inferTypes(inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
// We infer {} when there are no candidates for a type parameter
|
||||
const inferredTypes = map(inferences, inference => getTypeFromInference(inference) || emptyObjectType);
|
||||
combinedMapper = combineTypeMappers(mapper, createTypeMapper(root.inferTypeParameters, inferredTypes));
|
||||
inferTypes(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
combinedMapper = combineTypeMappers(mapper, context);
|
||||
}
|
||||
// Return union of trueType and falseType for 'any' since it matches anything
|
||||
if (checkType.flags & TypeFlags.Any) {
|
||||
@@ -8290,6 +8280,13 @@ namespace ts {
|
||||
}
|
||||
// Instantiate the extends type including inferences for 'infer T' type parameters
|
||||
const inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
|
||||
// Return falseType for a definitely false extends check. We check an instantations of the two
|
||||
// types with type parameters mapped to the wildcard type, the most permissive instantiations
|
||||
// possible (the wildcard type is assignable to and from all types). If those are not related,
|
||||
// then no instatiations will be and we can just return the false branch type.
|
||||
if (!isTypeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(inferredExtendsType))) {
|
||||
return instantiateType(root.falseType, mapper);
|
||||
}
|
||||
// Return trueType for a definitely true extends check. The definitely assignable relation excludes
|
||||
// type variable constraints from consideration. Without the definitely assignable relation, the type
|
||||
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
|
||||
@@ -8735,12 +8732,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isInferenceContext(mapper: TypeMapper): mapper is InferenceContext {
|
||||
return !!(<InferenceContext>mapper).signature;
|
||||
return !!(<InferenceContext>mapper).typeParameters;
|
||||
}
|
||||
|
||||
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
|
||||
return mapper && isInferenceContext(mapper) ?
|
||||
createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.compareTypes, mapper.inferences) :
|
||||
createInferenceContext(mapper.typeParameters, mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.compareTypes, mapper.inferences) :
|
||||
mapper;
|
||||
}
|
||||
|
||||
@@ -11395,9 +11392,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createInferenceContext(signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
|
||||
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
|
||||
function createInferenceContext(typeParameters: TypeParameter[], signature: Signature, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext {
|
||||
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(typeParameters, createInferenceInfo);
|
||||
const context = mapper as InferenceContext;
|
||||
context.typeParameters = typeParameters;
|
||||
context.signature = signature;
|
||||
context.inferences = inferences;
|
||||
context.flags = flags;
|
||||
@@ -11526,7 +11524,7 @@ namespace ts {
|
||||
const templateType = getTemplateTypeFromMappedType(target);
|
||||
const inference = createInferenceInfo(typeParameter);
|
||||
inferTypes([inference], sourceType, templateType);
|
||||
return getTypeFromInference(inference) || emptyObjectType;
|
||||
return getTypeFromInference(inference);
|
||||
}
|
||||
|
||||
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
|
||||
@@ -11545,7 +11543,7 @@ namespace ts {
|
||||
function getTypeFromInference(inference: InferenceInfo) {
|
||||
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
|
||||
inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
|
||||
undefined;
|
||||
emptyObjectType;
|
||||
}
|
||||
|
||||
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
|
||||
@@ -11918,63 +11916,68 @@ namespace ts {
|
||||
const inference = context.inferences[index];
|
||||
let inferredType = inference.inferredType;
|
||||
if (!inferredType) {
|
||||
if (inference.candidates) {
|
||||
// Extract all object literal types and replace them with a single widened and normalized type.
|
||||
const candidates = widenObjectLiteralCandidates(inference.candidates);
|
||||
// We widen inferred literal types if
|
||||
// all inferences were made to top-level ocurrences of the type parameter, and
|
||||
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
|
||||
// the type parameter was fixed during inference or does not occur at top-level in the return type.
|
||||
const signature = context.signature;
|
||||
const widenLiteralTypes = inference.topLevel &&
|
||||
!hasPrimitiveConstraint(inference.typeParameter) &&
|
||||
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
|
||||
// If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
|
||||
// union types were requested or if all inferences were made from the return type position, infer a
|
||||
// union type. Otherwise, infer a common supertype.
|
||||
const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ?
|
||||
getUnionType(baseCandidates, UnionReduction.Subtype) :
|
||||
getCommonSupertype(baseCandidates);
|
||||
inferredType = getWidenedType(unwidenedType);
|
||||
// If we have inferred 'never' but have contravariant candidates. To get a more specific type we
|
||||
// infer from the contravariant candidates instead.
|
||||
if (inferredType.flags & TypeFlags.Never && inference.contraCandidates) {
|
||||
const signature = context.signature;
|
||||
if (signature) {
|
||||
if (inference.candidates) {
|
||||
// Extract all object literal types and replace them with a single widened and normalized type.
|
||||
const candidates = widenObjectLiteralCandidates(inference.candidates);
|
||||
// We widen inferred literal types if
|
||||
// all inferences were made to top-level ocurrences of the type parameter, and
|
||||
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
|
||||
// the type parameter was fixed during inference or does not occur at top-level in the return type.
|
||||
const widenLiteralTypes = inference.topLevel &&
|
||||
!hasPrimitiveConstraint(inference.typeParameter) &&
|
||||
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
|
||||
// If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
|
||||
// union types were requested or if all inferences were made from the return type position, infer a
|
||||
// union type. Otherwise, infer a common supertype.
|
||||
const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ?
|
||||
getUnionType(baseCandidates, UnionReduction.Subtype) :
|
||||
getCommonSupertype(baseCandidates);
|
||||
inferredType = getWidenedType(unwidenedType);
|
||||
// If we have inferred 'never' but have contravariant candidates. To get a more specific type we
|
||||
// infer from the contravariant candidates instead.
|
||||
if (inferredType.flags & TypeFlags.Never && inference.contraCandidates) {
|
||||
inferredType = getCommonSubtype(inference.contraCandidates);
|
||||
}
|
||||
}
|
||||
else if (inference.contraCandidates) {
|
||||
// We only have contravariant inferences, infer the best common subtype of those
|
||||
inferredType = getCommonSubtype(inference.contraCandidates);
|
||||
}
|
||||
}
|
||||
else if (inference.contraCandidates) {
|
||||
// We only have contravariant inferences, infer the best common subtype of those
|
||||
inferredType = getCommonSubtype(inference.contraCandidates);
|
||||
}
|
||||
else if (context.flags & InferenceFlags.NoDefault) {
|
||||
// We use silentNeverType as the wildcard that signals no inferences.
|
||||
inferredType = silentNeverType;
|
||||
}
|
||||
else {
|
||||
// Infer either the default or the empty object type when no inferences were
|
||||
// made. It is important to remember that in this case, inference still
|
||||
// succeeds, meaning there is no error for not having inference candidates. An
|
||||
// inference error only occurs when there are *conflicting* candidates, i.e.
|
||||
// candidates with no common supertype.
|
||||
const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
|
||||
if (defaultType) {
|
||||
// Instantiate the default type. Any forward reference to a type
|
||||
// parameter should be instantiated to the empty object type.
|
||||
inferredType = instantiateType(defaultType,
|
||||
combineTypeMappers(
|
||||
createBackreferenceMapper(context.signature.typeParameters, index),
|
||||
context));
|
||||
else if (context.flags & InferenceFlags.NoDefault) {
|
||||
// We use silentNeverType as the wildcard that signals no inferences.
|
||||
inferredType = silentNeverType;
|
||||
}
|
||||
else {
|
||||
inferredType = getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
|
||||
// Infer either the default or the empty object type when no inferences were
|
||||
// made. It is important to remember that in this case, inference still
|
||||
// succeeds, meaning there is no error for not having inference candidates. An
|
||||
// inference error only occurs when there are *conflicting* candidates, i.e.
|
||||
// candidates with no common supertype.
|
||||
const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
|
||||
if (defaultType) {
|
||||
// Instantiate the default type. Any forward reference to a type
|
||||
// parameter should be instantiated to the empty object type.
|
||||
inferredType = instantiateType(defaultType,
|
||||
combineTypeMappers(
|
||||
createBackreferenceMapper(context.signature.typeParameters, index),
|
||||
context));
|
||||
}
|
||||
else {
|
||||
inferredType = getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
inferredType = getTypeFromInference(inference);
|
||||
}
|
||||
|
||||
inferredType = getWidenedUniqueESSymbolType(inferredType);
|
||||
inference.inferredType = inferredType;
|
||||
|
||||
const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]);
|
||||
const constraint = getConstraintOfTypeParameter(inference.typeParameter);
|
||||
if (constraint) {
|
||||
const instantiatedConstraint = instantiateType(constraint, context);
|
||||
if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
|
||||
@@ -15404,7 +15407,7 @@ namespace ts {
|
||||
for (const signature of signatures) {
|
||||
if (signature.typeParameters) {
|
||||
const isJavascript = isInJavaScriptFile(node);
|
||||
const inferenceContext = createInferenceContext(signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
const inferenceContext = createInferenceContext(signature.typeParameters, signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
const typeArguments = inferJsxTypeArguments(signature, node, inferenceContext);
|
||||
instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript));
|
||||
}
|
||||
@@ -16708,7 +16711,7 @@ namespace ts {
|
||||
|
||||
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
|
||||
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
|
||||
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes, compareTypes);
|
||||
const context = createInferenceContext(signature.typeParameters, signature, InferenceFlags.InferUnionTypes, compareTypes);
|
||||
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
|
||||
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
|
||||
inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
|
||||
@@ -17474,7 +17477,7 @@ namespace ts {
|
||||
|
||||
let candidate: Signature;
|
||||
const inferenceContext = originalCandidate.typeParameters ?
|
||||
createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None) :
|
||||
createInferenceContext(originalCandidate.typeParameters, originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None) :
|
||||
undefined;
|
||||
|
||||
while (true) {
|
||||
|
||||
@@ -3966,7 +3966,8 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface InferenceContext extends TypeMapper {
|
||||
signature: Signature; // Generic signature for which inferences are made
|
||||
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
|
||||
signature: Signature; // Generic signature for which inferences are made (if any)
|
||||
inferences: InferenceInfo[]; // Inferences made for each type parameter
|
||||
flags: InferenceFlags; // Inference flags
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
|
||||
@@ -17,7 +17,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: C
|
||||
tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'.
|
||||
tests/cases/conformance/types/conditional/inferTypes1.ts(81,44): error TS2344: Type 'U' does not satisfy the constraint 'string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322: Type 'T' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/conditional/inferTypes1.ts(143,40): error TS2322: Type 'T' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/conditional/inferTypes1.ts (16 errors) ====
|
||||
@@ -144,6 +144,15 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322:
|
||||
type T77<T> = T extends T76<infer X, infer Y> ? T76<X, Y> : never;
|
||||
type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
|
||||
|
||||
type Foo<T extends string, U extends T> = [T, U];
|
||||
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
|
||||
|
||||
type T90 = Bar<[string, string]>; // [string, string]
|
||||
type T91 = Bar<[string, "a"]>; // [string, "a"]
|
||||
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
|
||||
type T93 = Bar<["a", string]>; // never
|
||||
type T94 = Bar<[number, number]>; // never
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
@@ -206,4 +215,12 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(134,40): error TS2322:
|
||||
|
||||
type T80 = MatchingKeys<test, void>;
|
||||
type T81 = VoidKeys<test>;
|
||||
|
||||
// Repro from #22221
|
||||
|
||||
type MustBeString<T extends string> = T;
|
||||
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
|
||||
|
||||
type Test1 = EnsureIsString<"hello">; // "hello"
|
||||
type Test2 = EnsureIsString<42>; // never
|
||||
|
||||
@@ -88,6 +88,15 @@ type T76<T extends T[], U extends T> = { x: T };
|
||||
type T77<T> = T extends T76<infer X, infer Y> ? T76<X, Y> : never;
|
||||
type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
|
||||
|
||||
type Foo<T extends string, U extends T> = [T, U];
|
||||
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
|
||||
|
||||
type T90 = Bar<[string, string]>; // [string, string]
|
||||
type T91 = Bar<[string, "a"]>; // [string, "a"]
|
||||
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
|
||||
type T93 = Bar<["a", string]>; // never
|
||||
type T94 = Bar<[number, number]>; // never
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
@@ -148,6 +157,14 @@ interface test {
|
||||
|
||||
type T80 = MatchingKeys<test, void>;
|
||||
type T81 = VoidKeys<test>;
|
||||
|
||||
// Repro from #22221
|
||||
|
||||
type MustBeString<T extends string> = T;
|
||||
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
|
||||
|
||||
type Test1 = EnsureIsString<"hello">; // "hello"
|
||||
type Test2 = EnsureIsString<42>; // never
|
||||
|
||||
|
||||
//// [inferTypes1.js]
|
||||
|
||||
@@ -406,216 +406,279 @@ type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
|
||||
>X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42))
|
||||
>X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42))
|
||||
|
||||
type Foo<T extends string, U extends T> = [T, U];
|
||||
>Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 89, 9))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 89, 26))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 89, 9))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 89, 9))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 89, 26))
|
||||
|
||||
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 90, 9))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 90, 9))
|
||||
>Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66))
|
||||
>X : Symbol(X, Decl(inferTypes1.ts, 90, 33))
|
||||
>Y : Symbol(Y, Decl(inferTypes1.ts, 90, 42))
|
||||
>Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66))
|
||||
>X : Symbol(X, Decl(inferTypes1.ts, 90, 33))
|
||||
>Y : Symbol(Y, Decl(inferTypes1.ts, 90, 42))
|
||||
|
||||
type T90 = Bar<[string, string]>; // [string, string]
|
||||
>T90 : Symbol(T90, Decl(inferTypes1.ts, 90, 66))
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
|
||||
type T91 = Bar<[string, "a"]>; // [string, "a"]
|
||||
>T91 : Symbol(T91, Decl(inferTypes1.ts, 92, 33))
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
|
||||
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
|
||||
>T92 : Symbol(T92, Decl(inferTypes1.ts, 93, 30))
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
>x : Symbol(x, Decl(inferTypes1.ts, 94, 32))
|
||||
|
||||
type T93 = Bar<["a", string]>; // never
|
||||
>T93 : Symbol(T93, Decl(inferTypes1.ts, 94, 46))
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
|
||||
type T94 = Bar<[number, number]>; // never
|
||||
>T94 : Symbol(T94, Decl(inferTypes1.ts, 95, 30))
|
||||
>Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49))
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 87, 66))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 91, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 91, 44))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 91, 21))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 91, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 91, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 91, 44))
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 96, 33))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 100, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 100, 44))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 100, 21))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 100, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 100, 44))
|
||||
|
||||
type Jsonified<T> =
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 91, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
|
||||
T extends string | number | boolean | null ? T
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 96, 17))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 96, 33))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 96, 33))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 105, 17))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 105, 33))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 105, 33))
|
||||
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 87, 66))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 93, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 96, 33))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 102, 15))
|
||||
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 98, 21))
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 107, 21))
|
||||
|
||||
str: "literalstring",
|
||||
>str : Symbol(str, Decl(inferTypes1.ts, 100, 16))
|
||||
>str : Symbol(str, Decl(inferTypes1.ts, 109, 16))
|
||||
|
||||
fn: () => void,
|
||||
>fn : Symbol(fn, Decl(inferTypes1.ts, 101, 25))
|
||||
>fn : Symbol(fn, Decl(inferTypes1.ts, 110, 25))
|
||||
|
||||
date: Date,
|
||||
>date : Symbol(date, Decl(inferTypes1.ts, 102, 19))
|
||||
>date : Symbol(date, Decl(inferTypes1.ts, 111, 19))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
customClass: MyClass,
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 103, 15))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 110, 1))
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1))
|
||||
|
||||
obj: {
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 104, 25))
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25))
|
||||
|
||||
prop: "property",
|
||||
>prop : Symbol(prop, Decl(inferTypes1.ts, 105, 10))
|
||||
>prop : Symbol(prop, Decl(inferTypes1.ts, 114, 10))
|
||||
|
||||
clz: MyClass,
|
||||
>clz : Symbol(clz, Decl(inferTypes1.ts, 106, 25))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 110, 1))
|
||||
>clz : Symbol(clz, Decl(inferTypes1.ts, 115, 25))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1))
|
||||
|
||||
nested: { attr: Date }
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 107, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 108, 17))
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 110, 1))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1))
|
||||
|
||||
toJSON(): "correct";
|
||||
>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 112, 23))
|
||||
>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 121, 23))
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 114, 1))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 91, 77))
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 98, 21))
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 123, 1))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77))
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 107, 21))
|
||||
|
||||
declare let ex: JsonifiedExample;
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 117, 11))
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 114, 1))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11))
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 123, 1))
|
||||
|
||||
const z1: "correct" = ex.customClass;
|
||||
>z1 : Symbol(z1, Decl(inferTypes1.ts, 118, 5))
|
||||
>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 103, 15))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 117, 11))
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 103, 15))
|
||||
>z1 : Symbol(z1, Decl(inferTypes1.ts, 127, 5))
|
||||
>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11))
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15))
|
||||
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
>z2 : Symbol(z2, Decl(inferTypes1.ts, 119, 5))
|
||||
>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 108, 17))
|
||||
>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 107, 21))
|
||||
>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 104, 25))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 117, 11))
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 104, 25))
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 107, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 108, 17))
|
||||
>z2 : Symbol(z2, Decl(inferTypes1.ts, 128, 5))
|
||||
>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17))
|
||||
>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21))
|
||||
>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11))
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25))
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17))
|
||||
|
||||
// Repros from #21631
|
||||
|
||||
type A1<T, U extends A1<any, any>> = [T, U];
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 119, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 123, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 123, 10))
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 119, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 123, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 123, 10))
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 132, 10))
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 132, 10))
|
||||
|
||||
type B1<S> = S extends A1<infer T, infer U> ? [T, U] : never;
|
||||
>B1 : Symbol(B1, Decl(inferTypes1.ts, 123, 44))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 124, 8))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 124, 8))
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 119, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 124, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 124, 40))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 124, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 124, 40))
|
||||
>B1 : Symbol(B1, Decl(inferTypes1.ts, 132, 44))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 133, 8))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 133, 8))
|
||||
>A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 133, 40))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 133, 40))
|
||||
|
||||
type A2<T, U extends void> = [T, U];
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 124, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 126, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 126, 10))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 126, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 126, 10))
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 135, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 135, 10))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 135, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 135, 10))
|
||||
|
||||
type B2<S> = S extends A2<infer T, infer U> ? [T, U] : never;
|
||||
>B2 : Symbol(B2, Decl(inferTypes1.ts, 126, 36))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 127, 8))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 127, 8))
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 124, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 127, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 127, 40))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 127, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 127, 40))
|
||||
>B2 : Symbol(B2, Decl(inferTypes1.ts, 135, 36))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 136, 8))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 136, 8))
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 136, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 136, 40))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 136, 31))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 136, 40))
|
||||
|
||||
type C2<S, U extends void> = S extends A2<infer T, U> ? [T, U] : never;
|
||||
>C2 : Symbol(C2, Decl(inferTypes1.ts, 127, 61))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 128, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 128, 10))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 128, 8))
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 124, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 128, 47))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 128, 10))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 128, 47))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 128, 10))
|
||||
>C2 : Symbol(C2, Decl(inferTypes1.ts, 136, 61))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 137, 8))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 137, 10))
|
||||
>S : Symbol(S, Decl(inferTypes1.ts, 137, 8))
|
||||
>A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 47))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 137, 10))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 47))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 137, 10))
|
||||
|
||||
// Repro from #21735
|
||||
|
||||
type A<T> = T extends string ? { [P in T]: void; } : T;
|
||||
>A : Symbol(A, Decl(inferTypes1.ts, 128, 71))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 7))
|
||||
>P : Symbol(P, Decl(inferTypes1.ts, 132, 34))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 132, 7))
|
||||
>A : Symbol(A, Decl(inferTypes1.ts, 137, 71))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 141, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 141, 7))
|
||||
>P : Symbol(P, Decl(inferTypes1.ts, 141, 34))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 141, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 141, 7))
|
||||
|
||||
type B<T> = string extends T ? { [P in T]: void; } : T; // Error
|
||||
>B : Symbol(B, Decl(inferTypes1.ts, 132, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 7))
|
||||
>P : Symbol(P, Decl(inferTypes1.ts, 133, 34))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 133, 7))
|
||||
>B : Symbol(B, Decl(inferTypes1.ts, 141, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 142, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 142, 7))
|
||||
>P : Symbol(P, Decl(inferTypes1.ts, 142, 34))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 142, 7))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 142, 7))
|
||||
|
||||
// Repro from #22302
|
||||
|
||||
type MatchingKeys<T, U, K extends keyof T = keyof T> =
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 133, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 18))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 137, 20))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 137, 23))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 18))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 18))
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 146, 18))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 146, 20))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 146, 23))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 146, 18))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 146, 18))
|
||||
|
||||
K extends keyof T ? T[K] extends U ? K : never : never;
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 137, 23))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 18))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 137, 18))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 137, 23))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 137, 20))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 137, 23))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 146, 23))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 146, 18))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 146, 18))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 146, 23))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 146, 20))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 146, 23))
|
||||
|
||||
type VoidKeys<T> = MatchingKeys<T, void>;
|
||||
>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 138, 59))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 140, 14))
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 133, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 140, 14))
|
||||
>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 147, 59))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 149, 14))
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 149, 14))
|
||||
|
||||
interface test {
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 140, 41))
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 149, 41))
|
||||
|
||||
a: 1,
|
||||
>a : Symbol(test.a, Decl(inferTypes1.ts, 142, 16))
|
||||
>a : Symbol(test.a, Decl(inferTypes1.ts, 151, 16))
|
||||
|
||||
b: void
|
||||
>b : Symbol(test.b, Decl(inferTypes1.ts, 143, 9))
|
||||
>b : Symbol(test.b, Decl(inferTypes1.ts, 152, 9))
|
||||
}
|
||||
|
||||
type T80 = MatchingKeys<test, void>;
|
||||
>T80 : Symbol(T80, Decl(inferTypes1.ts, 145, 1))
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 133, 55))
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 140, 41))
|
||||
>T80 : Symbol(T80, Decl(inferTypes1.ts, 154, 1))
|
||||
>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55))
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 149, 41))
|
||||
|
||||
type T81 = VoidKeys<test>;
|
||||
>T81 : Symbol(T81, Decl(inferTypes1.ts, 147, 36))
|
||||
>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 138, 59))
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 140, 41))
|
||||
>T81 : Symbol(T81, Decl(inferTypes1.ts, 156, 36))
|
||||
>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 147, 59))
|
||||
>test : Symbol(test, Decl(inferTypes1.ts, 149, 41))
|
||||
|
||||
// Repro from #22221
|
||||
|
||||
type MustBeString<T extends string> = T;
|
||||
>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 157, 26))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 161, 18))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 161, 18))
|
||||
|
||||
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
|
||||
>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 162, 20))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 162, 20))
|
||||
>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 157, 26))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 162, 53))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 162, 53))
|
||||
|
||||
type Test1 = EnsureIsString<"hello">; // "hello"
|
||||
>Test1 : Symbol(Test1, Decl(inferTypes1.ts, 162, 69))
|
||||
>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40))
|
||||
|
||||
type Test2 = EnsureIsString<42>; // never
|
||||
>Test2 : Symbol(Test2, Decl(inferTypes1.ts, 164, 37))
|
||||
>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40))
|
||||
|
||||
|
||||
@@ -412,6 +412,46 @@ type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
|
||||
>X : X
|
||||
>X : X
|
||||
|
||||
type Foo<T extends string, U extends T> = [T, U];
|
||||
>Foo : [T, U]
|
||||
>T : T
|
||||
>U : U
|
||||
>T : T
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
|
||||
>Bar : Bar<T>
|
||||
>T : T
|
||||
>T : T
|
||||
>Foo : [T, U]
|
||||
>X : X
|
||||
>Y : Y
|
||||
>Foo : [T, U]
|
||||
>X : X
|
||||
>Y : Y
|
||||
|
||||
type T90 = Bar<[string, string]>; // [string, string]
|
||||
>T90 : [string, string]
|
||||
>Bar : Bar<T>
|
||||
|
||||
type T91 = Bar<[string, "a"]>; // [string, "a"]
|
||||
>T91 : [string, "a"]
|
||||
>Bar : Bar<T>
|
||||
|
||||
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
|
||||
>T92 : [string, "a"]
|
||||
>Bar : Bar<T>
|
||||
>x : string
|
||||
|
||||
type T93 = Bar<["a", string]>; // never
|
||||
>T93 : never
|
||||
>Bar : Bar<T>
|
||||
|
||||
type T94 = Bar<[number, number]>; // never
|
||||
>T94 : never
|
||||
>Bar : Bar<T>
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
@@ -626,3 +666,26 @@ type T81 = VoidKeys<test>;
|
||||
>VoidKeys : MatchingKeys<T, void, keyof T>
|
||||
>test : test
|
||||
|
||||
// Repro from #22221
|
||||
|
||||
type MustBeString<T extends string> = T;
|
||||
>MustBeString : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
|
||||
>EnsureIsString : EnsureIsString<T>
|
||||
>T : T
|
||||
>T : T
|
||||
>MustBeString : T
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
type Test1 = EnsureIsString<"hello">; // "hello"
|
||||
>Test1 : "hello"
|
||||
>EnsureIsString : EnsureIsString<T>
|
||||
|
||||
type Test2 = EnsureIsString<42>; // never
|
||||
>Test2 : never
|
||||
>EnsureIsString : EnsureIsString<T>
|
||||
|
||||
|
||||
@@ -90,6 +90,15 @@ type T76<T extends T[], U extends T> = { x: T };
|
||||
type T77<T> = T extends T76<infer X, infer Y> ? T76<X, Y> : never;
|
||||
type T78<T> = T extends T76<infer X, infer X> ? T76<X, X> : never;
|
||||
|
||||
type Foo<T extends string, U extends T> = [T, U];
|
||||
type Bar<T> = T extends Foo<infer X, infer Y> ? Foo<X, Y> : never;
|
||||
|
||||
type T90 = Bar<[string, string]>; // [string, string]
|
||||
type T91 = Bar<[string, "a"]>; // [string, "a"]
|
||||
type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"]
|
||||
type T93 = Bar<["a", string]>; // never
|
||||
type T94 = Bar<[number, number]>; // never
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
@@ -150,3 +159,11 @@ interface test {
|
||||
|
||||
type T80 = MatchingKeys<test, void>;
|
||||
type T81 = VoidKeys<test>;
|
||||
|
||||
// Repro from #22221
|
||||
|
||||
type MustBeString<T extends string> = T;
|
||||
type EnsureIsString<T> = T extends MustBeString<infer U> ? U : never;
|
||||
|
||||
type Test1 = EnsureIsString<"hello">; // "hello"
|
||||
type Test2 = EnsureIsString<42>; // never
|
||||
|
||||
Reference in New Issue
Block a user