mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Add depth limiter to isConstTypeVariable function (#54624)
This commit is contained in:
parent
e1a9290051
commit
84d8429fb6
@ -13538,14 +13538,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
|
||||
}
|
||||
|
||||
function isConstTypeVariable(type: Type | undefined): boolean {
|
||||
return !!(type && (
|
||||
function isConstTypeVariable(type: Type | undefined, depth = 0): boolean {
|
||||
return depth < 5 && !!(type && (
|
||||
type.flags & TypeFlags.TypeParameter && some((type as TypeParameter).symbol?.declarations, d => hasSyntacticModifier(d, ModifierFlags.Const)) ||
|
||||
type.flags & TypeFlags.Union && some((type as UnionType).types, isConstTypeVariable) ||
|
||||
type.flags & TypeFlags.IndexedAccess && isConstTypeVariable((type as IndexedAccessType).objectType) ||
|
||||
type.flags & TypeFlags.Conditional && isConstTypeVariable(getConstraintOfConditionalType(type as ConditionalType)) ||
|
||||
type.flags & TypeFlags.Substitution && isConstTypeVariable((type as SubstitutionType).baseType) ||
|
||||
isGenericTupleType(type) && findIndex(getElementTypes(type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t)) >= 0));
|
||||
type.flags & TypeFlags.Union && some((type as UnionType).types, t => isConstTypeVariable(t, depth)) ||
|
||||
type.flags & TypeFlags.IndexedAccess && isConstTypeVariable((type as IndexedAccessType).objectType, depth + 1) ||
|
||||
type.flags & TypeFlags.Conditional && isConstTypeVariable(getConstraintOfConditionalType(type as ConditionalType), depth + 1) ||
|
||||
type.flags & TypeFlags.Substitution && isConstTypeVariable((type as SubstitutionType).baseType, depth) ||
|
||||
isGenericTupleType(type) && findIndex(getElementTypes(type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t, depth)) >= 0));
|
||||
}
|
||||
|
||||
function getConstraintOfIndexedAccess(type: IndexedAccessType) {
|
||||
|
||||
22
tests/baselines/reference/circularBaseConstraint.errors.txt
Normal file
22
tests/baselines/reference/circularBaseConstraint.errors.txt
Normal file
@ -0,0 +1,22 @@
|
||||
circularBaseConstraint.ts(14,8): error TS2304: Cannot find name 'a'.
|
||||
|
||||
|
||||
==== circularBaseConstraint.ts (1 errors) ====
|
||||
// Repro from #54610
|
||||
|
||||
type A<T> = T;
|
||||
|
||||
type B<T> = T extends any[]
|
||||
? never
|
||||
: A<T> extends infer key
|
||||
? key extends keyof T
|
||||
? B<T[key]>
|
||||
: never
|
||||
: never;
|
||||
|
||||
function foo<T>() {
|
||||
`${a}` as B<T>;
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'a'.
|
||||
}
|
||||
|
||||
42
tests/baselines/reference/circularBaseConstraint.symbols
Normal file
42
tests/baselines/reference/circularBaseConstraint.symbols
Normal file
@ -0,0 +1,42 @@
|
||||
//// [tests/cases/compiler/circularBaseConstraint.ts] ////
|
||||
|
||||
=== circularBaseConstraint.ts ===
|
||||
// Repro from #54610
|
||||
|
||||
type A<T> = T;
|
||||
>A : Symbol(A, Decl(circularBaseConstraint.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 2, 7))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 2, 7))
|
||||
|
||||
type B<T> = T extends any[]
|
||||
>B : Symbol(B, Decl(circularBaseConstraint.ts, 2, 14))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 4, 7))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 4, 7))
|
||||
|
||||
? never
|
||||
: A<T> extends infer key
|
||||
>A : Symbol(A, Decl(circularBaseConstraint.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 4, 7))
|
||||
>key : Symbol(key, Decl(circularBaseConstraint.ts, 6, 24))
|
||||
|
||||
? key extends keyof T
|
||||
>key : Symbol(key, Decl(circularBaseConstraint.ts, 6, 24))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 4, 7))
|
||||
|
||||
? B<T[key]>
|
||||
>B : Symbol(B, Decl(circularBaseConstraint.ts, 2, 14))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 4, 7))
|
||||
>key : Symbol(key, Decl(circularBaseConstraint.ts, 6, 24))
|
||||
|
||||
: never
|
||||
: never;
|
||||
|
||||
function foo<T>() {
|
||||
>foo : Symbol(foo, Decl(circularBaseConstraint.ts, 10, 12))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 12, 13))
|
||||
|
||||
`${a}` as B<T>;
|
||||
>B : Symbol(B, Decl(circularBaseConstraint.ts, 2, 14))
|
||||
>T : Symbol(T, Decl(circularBaseConstraint.ts, 12, 13))
|
||||
}
|
||||
|
||||
27
tests/baselines/reference/circularBaseConstraint.types
Normal file
27
tests/baselines/reference/circularBaseConstraint.types
Normal file
@ -0,0 +1,27 @@
|
||||
//// [tests/cases/compiler/circularBaseConstraint.ts] ////
|
||||
|
||||
=== circularBaseConstraint.ts ===
|
||||
// Repro from #54610
|
||||
|
||||
type A<T> = T;
|
||||
>A : T
|
||||
|
||||
type B<T> = T extends any[]
|
||||
>B : B<T>
|
||||
|
||||
? never
|
||||
: A<T> extends infer key
|
||||
? key extends keyof T
|
||||
? B<T[key]>
|
||||
: never
|
||||
: never;
|
||||
|
||||
function foo<T>() {
|
||||
>foo : <T>() => void
|
||||
|
||||
`${a}` as B<T>;
|
||||
>`${a}` as B<T> : B<T>
|
||||
>`${a}` : string
|
||||
>a : any
|
||||
}
|
||||
|
||||
18
tests/cases/compiler/circularBaseConstraint.ts
Normal file
18
tests/cases/compiler/circularBaseConstraint.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// Repro from #54610
|
||||
|
||||
type A<T> = T;
|
||||
|
||||
type B<T> = T extends any[]
|
||||
? never
|
||||
: A<T> extends infer key
|
||||
? key extends keyof T
|
||||
? B<T[key]>
|
||||
: never
|
||||
: never;
|
||||
|
||||
function foo<T>() {
|
||||
`${a}` as B<T>;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user