Flatten immediately nested conditional types in the false position (#36583)
* Flatten immediately nested conditional types in the false position * Add test * Accept new baselines * Handle nested distributive types with different checkType * Allow deeply nested immediately resolving conditionals without any syntactic requirements or implementation contortions Extract logic into function Co-authored-by: Wesley Wigham <wewigham@microsoft.com>
This commit is contained in:
parent
2458c8a016
commit
9120497a33
|
@ -12889,65 +12889,82 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined): Type {
|
||||
const checkType = instantiateType(root.checkType, mapper);
|
||||
const extendsType = instantiateType(root.extendsType, mapper);
|
||||
if (checkType === wildcardType || extendsType === wildcardType) {
|
||||
return wildcardType;
|
||||
let result;
|
||||
let extraTypes: Type[] | undefined;
|
||||
// We loop here for an immediately nested conditional type in the false position, effectively treating
|
||||
// types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for
|
||||
// purposes of resolution. This means such types aren't subject to the instatiation depth limiter.
|
||||
while (true) {
|
||||
const checkType = instantiateType(root.checkType, mapper);
|
||||
const checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType);
|
||||
const extendsType = instantiateType(root.extendsType, mapper);
|
||||
if (checkType === wildcardType || extendsType === wildcardType) {
|
||||
return wildcardType;
|
||||
}
|
||||
let combinedMapper: TypeMapper | undefined;
|
||||
if (root.inferTypeParameters) {
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
// We skip inference of the possible `infer` types unles the `extendsType` _is_ an infer type
|
||||
// if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to
|
||||
// "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint
|
||||
// so in those cases we refain from performing inference and retain the uninfered type parameter
|
||||
if (!checkTypeInstantiable || !some(root.inferTypeParameters, t => t === extendsType)) {
|
||||
// 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(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
}
|
||||
combinedMapper = mergeTypeMappers(mapper, context.mapper);
|
||||
}
|
||||
// Instantiate the extends type including inferences for 'infer T' type parameters
|
||||
const inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
|
||||
// We attempt to resolve the conditional type only when the check and extends types are non-generic
|
||||
if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) {
|
||||
// Return falseType for a definitely false extends check. We check an instantiations 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 instantiations will be and we can just return the false branch type.
|
||||
if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) {
|
||||
// Return union of trueType and falseType for 'any' since it matches anything
|
||||
if (checkType.flags & TypeFlags.Any) {
|
||||
(extraTypes || (extraTypes = [])).push(instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper));
|
||||
}
|
||||
// If falseType is an immediately nested conditional type that isn't distributive or has an
|
||||
// identical checkType, switch to that type and loop.
|
||||
const falseType = root.falseType;
|
||||
if (falseType.flags & TypeFlags.Conditional) {
|
||||
const newRoot = (<ConditionalType>falseType).root;
|
||||
if (newRoot.node.parent === root.node && (!newRoot.isDistributive || newRoot.checkType === root.checkType)) {
|
||||
root = newRoot;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result = instantiateTypeWithoutDepthIncrease(falseType, mapper);
|
||||
break;
|
||||
}
|
||||
// Return trueType for a definitely true extends check. We check instantiations of the two
|
||||
// types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
|
||||
// that has no constraint. This ensures that, for example, the type
|
||||
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
|
||||
// doesn't immediately resolve to 'string' instead of being deferred.
|
||||
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
|
||||
result = instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Return a deferred type for a check that is neither definitely true nor definitely false
|
||||
const erasedCheckType = getActualTypeVariable(checkType);
|
||||
result = <ConditionalType>createType(TypeFlags.Conditional);
|
||||
result.root = root;
|
||||
result.checkType = erasedCheckType;
|
||||
result.extendsType = extendsType;
|
||||
result.mapper = mapper;
|
||||
result.combinedMapper = combinedMapper;
|
||||
result.aliasSymbol = root.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper!); // TODO: GH#18217
|
||||
break;
|
||||
}
|
||||
const checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType);
|
||||
let combinedMapper: TypeMapper | undefined;
|
||||
if (root.inferTypeParameters) {
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
// We skip inference of the possible `infer` types unles the `extendsType` _is_ an infer type
|
||||
// if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to
|
||||
// "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint
|
||||
// so in those cases we refain from performing inference and retain the uninfered type parameter
|
||||
if (!checkTypeInstantiable || !some(root.inferTypeParameters, t => t === extendsType)) {
|
||||
// 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(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
}
|
||||
combinedMapper = mergeTypeMappers(mapper, context.mapper);
|
||||
}
|
||||
// Instantiate the extends type including inferences for 'infer T' type parameters
|
||||
const inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
|
||||
// We attempt to resolve the conditional type only when the check and extends types are non-generic
|
||||
if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) {
|
||||
if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) {
|
||||
return instantiateType(root.trueType, combinedMapper || mapper);
|
||||
}
|
||||
// Return union of trueType and falseType for 'any' since it matches anything
|
||||
if (checkType.flags & TypeFlags.Any) {
|
||||
return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]);
|
||||
}
|
||||
// Return falseType for a definitely false extends check. We check an instantiations 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 instantiations will be and we can just return the false branch type.
|
||||
if (!isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) {
|
||||
return instantiateType(root.falseType, mapper);
|
||||
}
|
||||
// Return trueType for a definitely true extends check. We check instantiations of the two
|
||||
// types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
|
||||
// that has no constraint. This ensures that, for example, the type
|
||||
// type Foo<T extends { x: any }> = T extends { x: string } ? string : number
|
||||
// doesn't immediately resolve to 'string' instead of being deferred.
|
||||
if (isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
|
||||
return instantiateType(root.trueType, combinedMapper || mapper);
|
||||
}
|
||||
}
|
||||
// Return a deferred type for a check that is neither definitely true nor definitely false
|
||||
const erasedCheckType = getActualTypeVariable(checkType);
|
||||
const result = <ConditionalType>createType(TypeFlags.Conditional);
|
||||
result.root = root;
|
||||
result.checkType = erasedCheckType;
|
||||
result.extendsType = extendsType;
|
||||
result.mapper = mapper;
|
||||
result.combinedMapper = combinedMapper;
|
||||
result.aliasSymbol = root.aliasSymbol;
|
||||
result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper!); // TODO: GH#18217
|
||||
return result;
|
||||
return extraTypes ? getUnionType(append(extraTypes, result)) : result;
|
||||
}
|
||||
|
||||
function getTrueTypeFromConditionalType(type: ConditionalType) {
|
||||
|
@ -13929,6 +13946,17 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be used to avoid the penalty on instantiation depth for types which result from immediate
|
||||
* simplification. It essentially removes the depth increase done in `instantiateType`.
|
||||
*/
|
||||
function instantiateTypeWithoutDepthIncrease(type: Type, mapper: TypeMapper | undefined) {
|
||||
instantiationDepth--;
|
||||
const result = instantiateType(type, mapper);
|
||||
instantiationDepth++;
|
||||
return result;
|
||||
}
|
||||
|
||||
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
|
||||
const flags = type.flags;
|
||||
if (flags & TypeFlags.TypeParameter) {
|
||||
|
|
116
tests/baselines/reference/deeplyNestedConditionalTypes.js
Normal file
116
tests/baselines/reference/deeplyNestedConditionalTypes.js
Normal file
|
@ -0,0 +1,116 @@
|
|||
//// [deeplyNestedConditionalTypes.ts]
|
||||
type Foo<T> =
|
||||
T extends 0 ? '0' :
|
||||
T extends 1 ? '1' :
|
||||
T extends 2 ? '2' :
|
||||
T extends 3 ? '3' :
|
||||
T extends 4 ? '4' :
|
||||
T extends 5 ? '5' :
|
||||
T extends 6 ? '6' :
|
||||
T extends 7 ? '7' :
|
||||
T extends 8 ? '8' :
|
||||
T extends 9 ? '9' :
|
||||
T extends 10 ? '10' :
|
||||
T extends 11 ? '11' :
|
||||
T extends 12 ? '12' :
|
||||
T extends 13 ? '13' :
|
||||
T extends 14 ? '14' :
|
||||
T extends 15 ? '15' :
|
||||
T extends 16 ? '16' :
|
||||
T extends 17 ? '17' :
|
||||
T extends 18 ? '18' :
|
||||
T extends 19 ? '19' :
|
||||
T extends 20 ? '20' :
|
||||
T extends 21 ? '21' :
|
||||
T extends 22 ? '22' :
|
||||
T extends 23 ? '23' :
|
||||
T extends 24 ? '24' :
|
||||
T extends 25 ? '25' :
|
||||
T extends 26 ? '26' :
|
||||
T extends 27 ? '27' :
|
||||
T extends 28 ? '28' :
|
||||
T extends 29 ? '29' :
|
||||
T extends 30 ? '30' :
|
||||
T extends 31 ? '31' :
|
||||
T extends 32 ? '32' :
|
||||
T extends 33 ? '33' :
|
||||
T extends 34 ? '34' :
|
||||
T extends 35 ? '35' :
|
||||
T extends 36 ? '36' :
|
||||
T extends 37 ? '37' :
|
||||
T extends 38 ? '38' :
|
||||
T extends 39 ? '39' :
|
||||
T extends 40 ? '40' :
|
||||
T extends 41 ? '41' :
|
||||
T extends 42 ? '42' :
|
||||
T extends 43 ? '43' :
|
||||
T extends 44 ? '44' :
|
||||
T extends 45 ? '45' :
|
||||
T extends 46 ? '46' :
|
||||
T extends 47 ? '47' :
|
||||
T extends 48 ? '48' :
|
||||
T extends 49 ? '49' :
|
||||
T extends 50 ? '50' :
|
||||
T extends 51 ? '51' :
|
||||
T extends 52 ? '52' :
|
||||
T extends 53 ? '53' :
|
||||
T extends 54 ? '54' :
|
||||
T extends 55 ? '55' :
|
||||
T extends 56 ? '56' :
|
||||
T extends 57 ? '57' :
|
||||
T extends 58 ? '58' :
|
||||
T extends 59 ? '59' :
|
||||
T extends 60 ? '60' :
|
||||
T extends 61 ? '61' :
|
||||
T extends 62 ? '62' :
|
||||
T extends 63 ? '63' :
|
||||
T extends 64 ? '64' :
|
||||
T extends 65 ? '65' :
|
||||
T extends 66 ? '66' :
|
||||
T extends 67 ? '67' :
|
||||
T extends 68 ? '68' :
|
||||
T extends 69 ? '69' :
|
||||
T extends 70 ? '70' :
|
||||
T extends 71 ? '71' :
|
||||
T extends 72 ? '72' :
|
||||
T extends 73 ? '73' :
|
||||
T extends 74 ? '74' :
|
||||
T extends 75 ? '75' :
|
||||
T extends 76 ? '76' :
|
||||
T extends 77 ? '77' :
|
||||
T extends 78 ? '78' :
|
||||
T extends 79 ? '79' :
|
||||
T extends 80 ? '80' :
|
||||
T extends 81 ? '81' :
|
||||
T extends 82 ? '82' :
|
||||
T extends 83 ? '83' :
|
||||
T extends 84 ? '84' :
|
||||
T extends 85 ? '85' :
|
||||
T extends 86 ? '86' :
|
||||
T extends 87 ? '87' :
|
||||
T extends 88 ? '88' :
|
||||
T extends 89 ? '89' :
|
||||
T extends 90 ? '90' :
|
||||
T extends 91 ? '91' :
|
||||
T extends 92 ? '92' :
|
||||
T extends 93 ? '93' :
|
||||
T extends 94 ? '94' :
|
||||
T extends 95 ? '95' :
|
||||
T extends 96 ? '96' :
|
||||
T extends 97 ? '97' :
|
||||
T extends 98 ? '98' :
|
||||
T extends 99 ? '99' :
|
||||
never;
|
||||
|
||||
type T0 = Foo<99>;
|
||||
type T1 = Foo<any>;
|
||||
|
||||
|
||||
//// [deeplyNestedConditionalTypes.js]
|
||||
"use strict";
|
||||
|
||||
|
||||
//// [deeplyNestedConditionalTypes.d.ts]
|
||||
declare type Foo<T> = T extends 0 ? '0' : T extends 1 ? '1' : T extends 2 ? '2' : T extends 3 ? '3' : T extends 4 ? '4' : T extends 5 ? '5' : T extends 6 ? '6' : T extends 7 ? '7' : T extends 8 ? '8' : T extends 9 ? '9' : T extends 10 ? '10' : T extends 11 ? '11' : T extends 12 ? '12' : T extends 13 ? '13' : T extends 14 ? '14' : T extends 15 ? '15' : T extends 16 ? '16' : T extends 17 ? '17' : T extends 18 ? '18' : T extends 19 ? '19' : T extends 20 ? '20' : T extends 21 ? '21' : T extends 22 ? '22' : T extends 23 ? '23' : T extends 24 ? '24' : T extends 25 ? '25' : T extends 26 ? '26' : T extends 27 ? '27' : T extends 28 ? '28' : T extends 29 ? '29' : T extends 30 ? '30' : T extends 31 ? '31' : T extends 32 ? '32' : T extends 33 ? '33' : T extends 34 ? '34' : T extends 35 ? '35' : T extends 36 ? '36' : T extends 37 ? '37' : T extends 38 ? '38' : T extends 39 ? '39' : T extends 40 ? '40' : T extends 41 ? '41' : T extends 42 ? '42' : T extends 43 ? '43' : T extends 44 ? '44' : T extends 45 ? '45' : T extends 46 ? '46' : T extends 47 ? '47' : T extends 48 ? '48' : T extends 49 ? '49' : T extends 50 ? '50' : T extends 51 ? '51' : T extends 52 ? '52' : T extends 53 ? '53' : T extends 54 ? '54' : T extends 55 ? '55' : T extends 56 ? '56' : T extends 57 ? '57' : T extends 58 ? '58' : T extends 59 ? '59' : T extends 60 ? '60' : T extends 61 ? '61' : T extends 62 ? '62' : T extends 63 ? '63' : T extends 64 ? '64' : T extends 65 ? '65' : T extends 66 ? '66' : T extends 67 ? '67' : T extends 68 ? '68' : T extends 69 ? '69' : T extends 70 ? '70' : T extends 71 ? '71' : T extends 72 ? '72' : T extends 73 ? '73' : T extends 74 ? '74' : T extends 75 ? '75' : T extends 76 ? '76' : T extends 77 ? '77' : T extends 78 ? '78' : T extends 79 ? '79' : T extends 80 ? '80' : T extends 81 ? '81' : T extends 82 ? '82' : T extends 83 ? '83' : T extends 84 ? '84' : T extends 85 ? '85' : T extends 86 ? '86' : T extends 87 ? '87' : T extends 88 ? '88' : T extends 89 ? '89' : T extends 90 ? '90' : T extends 91 ? '91' : T extends 92 ? '92' : T extends 93 ? '93' : T extends 94 ? '94' : T extends 95 ? '95' : T extends 96 ? '96' : T extends 97 ? '97' : T extends 98 ? '98' : T extends 99 ? '99' : never;
|
||||
declare type T0 = Foo<99>;
|
||||
declare type T1 = Foo<any>;
|
315
tests/baselines/reference/deeplyNestedConditionalTypes.symbols
Normal file
315
tests/baselines/reference/deeplyNestedConditionalTypes.symbols
Normal file
|
@ -0,0 +1,315 @@
|
|||
=== tests/cases/compiler/deeplyNestedConditionalTypes.ts ===
|
||||
type Foo<T> =
|
||||
>Foo : Symbol(Foo, Decl(deeplyNestedConditionalTypes.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 0 ? '0' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 1 ? '1' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 2 ? '2' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 3 ? '3' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 4 ? '4' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 5 ? '5' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 6 ? '6' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 7 ? '7' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 8 ? '8' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 9 ? '9' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 10 ? '10' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 11 ? '11' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 12 ? '12' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 13 ? '13' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 14 ? '14' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 15 ? '15' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 16 ? '16' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 17 ? '17' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 18 ? '18' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 19 ? '19' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 20 ? '20' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 21 ? '21' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 22 ? '22' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 23 ? '23' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 24 ? '24' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 25 ? '25' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 26 ? '26' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 27 ? '27' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 28 ? '28' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 29 ? '29' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 30 ? '30' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 31 ? '31' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 32 ? '32' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 33 ? '33' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 34 ? '34' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 35 ? '35' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 36 ? '36' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 37 ? '37' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 38 ? '38' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 39 ? '39' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 40 ? '40' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 41 ? '41' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 42 ? '42' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 43 ? '43' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 44 ? '44' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 45 ? '45' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 46 ? '46' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 47 ? '47' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 48 ? '48' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 49 ? '49' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 50 ? '50' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 51 ? '51' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 52 ? '52' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 53 ? '53' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 54 ? '54' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 55 ? '55' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 56 ? '56' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 57 ? '57' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 58 ? '58' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 59 ? '59' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 60 ? '60' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 61 ? '61' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 62 ? '62' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 63 ? '63' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 64 ? '64' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 65 ? '65' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 66 ? '66' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 67 ? '67' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 68 ? '68' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 69 ? '69' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 70 ? '70' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 71 ? '71' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 72 ? '72' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 73 ? '73' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 74 ? '74' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 75 ? '75' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 76 ? '76' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 77 ? '77' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 78 ? '78' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 79 ? '79' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 80 ? '80' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 81 ? '81' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 82 ? '82' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 83 ? '83' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 84 ? '84' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 85 ? '85' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 86 ? '86' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 87 ? '87' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 88 ? '88' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 89 ? '89' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 90 ? '90' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 91 ? '91' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 92 ? '92' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 93 ? '93' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 94 ? '94' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 95 ? '95' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 96 ? '96' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 97 ? '97' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 98 ? '98' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
T extends 99 ? '99' :
|
||||
>T : Symbol(T, Decl(deeplyNestedConditionalTypes.ts, 0, 9))
|
||||
|
||||
never;
|
||||
|
||||
type T0 = Foo<99>;
|
||||
>T0 : Symbol(T0, Decl(deeplyNestedConditionalTypes.ts, 101, 10))
|
||||
>Foo : Symbol(Foo, Decl(deeplyNestedConditionalTypes.ts, 0, 0))
|
||||
|
||||
type T1 = Foo<any>;
|
||||
>T1 : Symbol(T1, Decl(deeplyNestedConditionalTypes.ts, 103, 18))
|
||||
>Foo : Symbol(Foo, Decl(deeplyNestedConditionalTypes.ts, 0, 0))
|
||||
|
112
tests/baselines/reference/deeplyNestedConditionalTypes.types
Normal file
112
tests/baselines/reference/deeplyNestedConditionalTypes.types
Normal file
|
@ -0,0 +1,112 @@
|
|||
=== tests/cases/compiler/deeplyNestedConditionalTypes.ts ===
|
||||
type Foo<T> =
|
||||
>Foo : Foo<T>
|
||||
|
||||
T extends 0 ? '0' :
|
||||
T extends 1 ? '1' :
|
||||
T extends 2 ? '2' :
|
||||
T extends 3 ? '3' :
|
||||
T extends 4 ? '4' :
|
||||
T extends 5 ? '5' :
|
||||
T extends 6 ? '6' :
|
||||
T extends 7 ? '7' :
|
||||
T extends 8 ? '8' :
|
||||
T extends 9 ? '9' :
|
||||
T extends 10 ? '10' :
|
||||
T extends 11 ? '11' :
|
||||
T extends 12 ? '12' :
|
||||
T extends 13 ? '13' :
|
||||
T extends 14 ? '14' :
|
||||
T extends 15 ? '15' :
|
||||
T extends 16 ? '16' :
|
||||
T extends 17 ? '17' :
|
||||
T extends 18 ? '18' :
|
||||
T extends 19 ? '19' :
|
||||
T extends 20 ? '20' :
|
||||
T extends 21 ? '21' :
|
||||
T extends 22 ? '22' :
|
||||
T extends 23 ? '23' :
|
||||
T extends 24 ? '24' :
|
||||
T extends 25 ? '25' :
|
||||
T extends 26 ? '26' :
|
||||
T extends 27 ? '27' :
|
||||
T extends 28 ? '28' :
|
||||
T extends 29 ? '29' :
|
||||
T extends 30 ? '30' :
|
||||
T extends 31 ? '31' :
|
||||
T extends 32 ? '32' :
|
||||
T extends 33 ? '33' :
|
||||
T extends 34 ? '34' :
|
||||
T extends 35 ? '35' :
|
||||
T extends 36 ? '36' :
|
||||
T extends 37 ? '37' :
|
||||
T extends 38 ? '38' :
|
||||
T extends 39 ? '39' :
|
||||
T extends 40 ? '40' :
|
||||
T extends 41 ? '41' :
|
||||
T extends 42 ? '42' :
|
||||
T extends 43 ? '43' :
|
||||
T extends 44 ? '44' :
|
||||
T extends 45 ? '45' :
|
||||
T extends 46 ? '46' :
|
||||
T extends 47 ? '47' :
|
||||
T extends 48 ? '48' :
|
||||
T extends 49 ? '49' :
|
||||
T extends 50 ? '50' :
|
||||
T extends 51 ? '51' :
|
||||
T extends 52 ? '52' :
|
||||
T extends 53 ? '53' :
|
||||
T extends 54 ? '54' :
|
||||
T extends 55 ? '55' :
|
||||
T extends 56 ? '56' :
|
||||
T extends 57 ? '57' :
|
||||
T extends 58 ? '58' :
|
||||
T extends 59 ? '59' :
|
||||
T extends 60 ? '60' :
|
||||
T extends 61 ? '61' :
|
||||
T extends 62 ? '62' :
|
||||
T extends 63 ? '63' :
|
||||
T extends 64 ? '64' :
|
||||
T extends 65 ? '65' :
|
||||
T extends 66 ? '66' :
|
||||
T extends 67 ? '67' :
|
||||
T extends 68 ? '68' :
|
||||
T extends 69 ? '69' :
|
||||
T extends 70 ? '70' :
|
||||
T extends 71 ? '71' :
|
||||
T extends 72 ? '72' :
|
||||
T extends 73 ? '73' :
|
||||
T extends 74 ? '74' :
|
||||
T extends 75 ? '75' :
|
||||
T extends 76 ? '76' :
|
||||
T extends 77 ? '77' :
|
||||
T extends 78 ? '78' :
|
||||
T extends 79 ? '79' :
|
||||
T extends 80 ? '80' :
|
||||
T extends 81 ? '81' :
|
||||
T extends 82 ? '82' :
|
||||
T extends 83 ? '83' :
|
||||
T extends 84 ? '84' :
|
||||
T extends 85 ? '85' :
|
||||
T extends 86 ? '86' :
|
||||
T extends 87 ? '87' :
|
||||
T extends 88 ? '88' :
|
||||
T extends 89 ? '89' :
|
||||
T extends 90 ? '90' :
|
||||
T extends 91 ? '91' :
|
||||
T extends 92 ? '92' :
|
||||
T extends 93 ? '93' :
|
||||
T extends 94 ? '94' :
|
||||
T extends 95 ? '95' :
|
||||
T extends 96 ? '96' :
|
||||
T extends 97 ? '97' :
|
||||
T extends 98 ? '98' :
|
||||
T extends 99 ? '99' :
|
||||
never;
|
||||
|
||||
type T0 = Foo<99>;
|
||||
>T0 : "99"
|
||||
|
||||
type T1 = Foo<any>;
|
||||
>T1 : "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | "22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31" | "32" | "33" | "34" | "35" | "36" | "37" | "38" | "39" | "40" | "41" | "42" | "43" | "44" | "45" | "46" | "47" | "48" | "49" | "50" | "51" | "52" | "53" | "54" | "55" | "56" | "57" | "58" | "59" | "60" | "61" | "62" | "63" | "64" | "65" | "66" | "67" | "68" | "69" | "70" | "71" | "72" | "73" | "74" | "75" | "76" | "77" | "78" | "79" | "80" | "81" | "82" | "83" | "84" | "85" | "86" | "87" | "88" | "89" | "90" | "91" | "92" | "93" | "94" | "95" | "96" | "97" | "98" | "99"
|
||||
|
108
tests/cases/compiler/deeplyNestedConditionalTypes.ts
Normal file
108
tests/cases/compiler/deeplyNestedConditionalTypes.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
type Foo<T> =
|
||||
T extends 0 ? '0' :
|
||||
T extends 1 ? '1' :
|
||||
T extends 2 ? '2' :
|
||||
T extends 3 ? '3' :
|
||||
T extends 4 ? '4' :
|
||||
T extends 5 ? '5' :
|
||||
T extends 6 ? '6' :
|
||||
T extends 7 ? '7' :
|
||||
T extends 8 ? '8' :
|
||||
T extends 9 ? '9' :
|
||||
T extends 10 ? '10' :
|
||||
T extends 11 ? '11' :
|
||||
T extends 12 ? '12' :
|
||||
T extends 13 ? '13' :
|
||||
T extends 14 ? '14' :
|
||||
T extends 15 ? '15' :
|
||||
T extends 16 ? '16' :
|
||||
T extends 17 ? '17' :
|
||||
T extends 18 ? '18' :
|
||||
T extends 19 ? '19' :
|
||||
T extends 20 ? '20' :
|
||||
T extends 21 ? '21' :
|
||||
T extends 22 ? '22' :
|
||||
T extends 23 ? '23' :
|
||||
T extends 24 ? '24' :
|
||||
T extends 25 ? '25' :
|
||||
T extends 26 ? '26' :
|
||||
T extends 27 ? '27' :
|
||||
T extends 28 ? '28' :
|
||||
T extends 29 ? '29' :
|
||||
T extends 30 ? '30' :
|
||||
T extends 31 ? '31' :
|
||||
T extends 32 ? '32' :
|
||||
T extends 33 ? '33' :
|
||||
T extends 34 ? '34' :
|
||||
T extends 35 ? '35' :
|
||||
T extends 36 ? '36' :
|
||||
T extends 37 ? '37' :
|
||||
T extends 38 ? '38' :
|
||||
T extends 39 ? '39' :
|
||||
T extends 40 ? '40' :
|
||||
T extends 41 ? '41' :
|
||||
T extends 42 ? '42' :
|
||||
T extends 43 ? '43' :
|
||||
T extends 44 ? '44' :
|
||||
T extends 45 ? '45' :
|
||||
T extends 46 ? '46' :
|
||||
T extends 47 ? '47' :
|
||||
T extends 48 ? '48' :
|
||||
T extends 49 ? '49' :
|
||||
T extends 50 ? '50' :
|
||||
T extends 51 ? '51' :
|
||||
T extends 52 ? '52' :
|
||||
T extends 53 ? '53' :
|
||||
T extends 54 ? '54' :
|
||||
T extends 55 ? '55' :
|
||||
T extends 56 ? '56' :
|
||||
T extends 57 ? '57' :
|
||||
T extends 58 ? '58' :
|
||||
T extends 59 ? '59' :
|
||||
T extends 60 ? '60' :
|
||||
T extends 61 ? '61' :
|
||||
T extends 62 ? '62' :
|
||||
T extends 63 ? '63' :
|
||||
T extends 64 ? '64' :
|
||||
T extends 65 ? '65' :
|
||||
T extends 66 ? '66' :
|
||||
T extends 67 ? '67' :
|
||||
T extends 68 ? '68' :
|
||||
T extends 69 ? '69' :
|
||||
T extends 70 ? '70' :
|
||||
T extends 71 ? '71' :
|
||||
T extends 72 ? '72' :
|
||||
T extends 73 ? '73' :
|
||||
T extends 74 ? '74' :
|
||||
T extends 75 ? '75' :
|
||||
T extends 76 ? '76' :
|
||||
T extends 77 ? '77' :
|
||||
T extends 78 ? '78' :
|
||||
T extends 79 ? '79' :
|
||||
T extends 80 ? '80' :
|
||||
T extends 81 ? '81' :
|
||||
T extends 82 ? '82' :
|
||||
T extends 83 ? '83' :
|
||||
T extends 84 ? '84' :
|
||||
T extends 85 ? '85' :
|
||||
T extends 86 ? '86' :
|
||||
T extends 87 ? '87' :
|
||||
T extends 88 ? '88' :
|
||||
T extends 89 ? '89' :
|
||||
T extends 90 ? '90' :
|
||||
T extends 91 ? '91' :
|
||||
T extends 92 ? '92' :
|
||||
T extends 93 ? '93' :
|
||||
T extends 94 ? '94' :
|
||||
T extends 95 ? '95' :
|
||||
T extends 96 ? '96' :
|
||||
T extends 97 ? '97' :
|
||||
T extends 98 ? '98' :
|
||||
T extends 99 ? '99' :
|
||||
never;
|
||||
|
||||
type T0 = Foo<99>;
|
||||
type T1 = Foo<any>;
|
Loading…
Reference in a new issue