mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Exclude typeof this from check in isConstantReference (#52680)
This commit is contained in:
parent
1c822c42a4
commit
57ebd99ff2
@ -26091,10 +26091,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function isConstantReference(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier: {
|
||||
const symbol = getResolvedSymbol(node as Identifier);
|
||||
return isConstVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol);
|
||||
}
|
||||
case SyntaxKind.Identifier:
|
||||
if (!isThisInTypeQuery(node)) {
|
||||
const symbol = getResolvedSymbol(node as Identifier);
|
||||
return isConstVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
// The resolvedSymbol property is initialized by checkPropertyAccess or checkElementAccess before we get here.
|
||||
|
||||
77
tests/baselines/reference/thisInTypeQuery.symbols
Normal file
77
tests/baselines/reference/thisInTypeQuery.symbols
Normal file
@ -0,0 +1,77 @@
|
||||
=== tests/cases/compiler/thisInTypeQuery.ts ===
|
||||
// Repros from #52672
|
||||
|
||||
function assert(condition: unknown): asserts condition {
|
||||
>assert : Symbol(assert, Decl(thisInTypeQuery.ts, 0, 0))
|
||||
>condition : Symbol(condition, Decl(thisInTypeQuery.ts, 2, 16))
|
||||
>condition : Symbol(condition, Decl(thisInTypeQuery.ts, 2, 16))
|
||||
|
||||
if (!condition) {
|
||||
>condition : Symbol(condition, Decl(thisInTypeQuery.ts, 2, 16))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
>MyClass : Symbol(MyClass, Decl(thisInTypeQuery.ts, 6, 1))
|
||||
|
||||
private map = {
|
||||
>map : Symbol(MyClass.map, Decl(thisInTypeQuery.ts, 8, 15))
|
||||
|
||||
my_key: 'example_value'
|
||||
>my_key : Symbol(my_key, Decl(thisInTypeQuery.ts, 9, 19))
|
||||
|
||||
};
|
||||
|
||||
runTypeFails() {
|
||||
>runTypeFails : Symbol(MyClass.runTypeFails, Decl(thisInTypeQuery.ts, 11, 6))
|
||||
|
||||
const params = null as any as { a: { key: string } } | null;
|
||||
>params : Symbol(params, Decl(thisInTypeQuery.ts, 14, 13))
|
||||
>a : Symbol(a, Decl(thisInTypeQuery.ts, 14, 39))
|
||||
>key : Symbol(key, Decl(thisInTypeQuery.ts, 14, 44))
|
||||
|
||||
assert(params);
|
||||
>assert : Symbol(assert, Decl(thisInTypeQuery.ts, 0, 0))
|
||||
>params : Symbol(params, Decl(thisInTypeQuery.ts, 14, 13))
|
||||
|
||||
type Key = keyof typeof this.map;
|
||||
>Key : Symbol(Key, Decl(thisInTypeQuery.ts, 15, 23))
|
||||
>this.map : Symbol(MyClass.map, Decl(thisInTypeQuery.ts, 8, 15))
|
||||
>this : Symbol(MyClass, Decl(thisInTypeQuery.ts, 6, 1))
|
||||
>map : Symbol(MyClass.map, Decl(thisInTypeQuery.ts, 8, 15))
|
||||
|
||||
this.map[params.a.key as Key];
|
||||
>this.map : Symbol(MyClass.map, Decl(thisInTypeQuery.ts, 8, 15))
|
||||
>this : Symbol(MyClass, Decl(thisInTypeQuery.ts, 6, 1))
|
||||
>map : Symbol(MyClass.map, Decl(thisInTypeQuery.ts, 8, 15))
|
||||
>params.a.key : Symbol(key, Decl(thisInTypeQuery.ts, 14, 44))
|
||||
>params.a : Symbol(a, Decl(thisInTypeQuery.ts, 14, 39))
|
||||
>params : Symbol(params, Decl(thisInTypeQuery.ts, 14, 13))
|
||||
>a : Symbol(a, Decl(thisInTypeQuery.ts, 14, 39))
|
||||
>key : Symbol(key, Decl(thisInTypeQuery.ts, 14, 44))
|
||||
>Key : Symbol(Key, Decl(thisInTypeQuery.ts, 15, 23))
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(thisInTypeQuery.ts, 19, 1))
|
||||
|
||||
foo() {
|
||||
>foo : Symbol(C.foo, Decl(thisInTypeQuery.ts, 21, 9))
|
||||
|
||||
const x = !!true;
|
||||
>x : Symbol(x, Decl(thisInTypeQuery.ts, 23, 9))
|
||||
|
||||
if (x) {
|
||||
>x : Symbol(x, Decl(thisInTypeQuery.ts, 23, 9))
|
||||
|
||||
type T0 = typeof this;
|
||||
>T0 : Symbol(T0, Decl(thisInTypeQuery.ts, 24, 12))
|
||||
>this : Symbol(C, Decl(thisInTypeQuery.ts, 19, 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
tests/baselines/reference/thisInTypeQuery.types
Normal file
89
tests/baselines/reference/thisInTypeQuery.types
Normal file
@ -0,0 +1,89 @@
|
||||
=== tests/cases/compiler/thisInTypeQuery.ts ===
|
||||
// Repros from #52672
|
||||
|
||||
function assert(condition: unknown): asserts condition {
|
||||
>assert : (condition: unknown) => asserts condition
|
||||
>condition : unknown
|
||||
|
||||
if (!condition) {
|
||||
>!condition : boolean
|
||||
>condition : unknown
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
>MyClass : MyClass
|
||||
|
||||
private map = {
|
||||
>map : { my_key: string; }
|
||||
>{ my_key: 'example_value' } : { my_key: string; }
|
||||
|
||||
my_key: 'example_value'
|
||||
>my_key : string
|
||||
>'example_value' : "example_value"
|
||||
|
||||
};
|
||||
|
||||
runTypeFails() {
|
||||
>runTypeFails : () => void
|
||||
|
||||
const params = null as any as { a: { key: string } } | null;
|
||||
>params : { a: { key: string;}; } | null
|
||||
>null as any as { a: { key: string } } | null : { a: { key: string;}; } | null
|
||||
>null as any : any
|
||||
>null : null
|
||||
>a : { key: string; }
|
||||
>key : string
|
||||
>null : null
|
||||
|
||||
assert(params);
|
||||
>assert(params) : void
|
||||
>assert : (condition: unknown) => asserts condition
|
||||
>params : { a: { key: string; }; } | null
|
||||
|
||||
type Key = keyof typeof this.map;
|
||||
>Key : "my_key"
|
||||
>this.map : { my_key: string; }
|
||||
>this : this
|
||||
>map : { my_key: string; }
|
||||
|
||||
this.map[params.a.key as Key];
|
||||
>this.map[params.a.key as Key] : string
|
||||
>this.map : { my_key: string; }
|
||||
>this : this
|
||||
>map : { my_key: string; }
|
||||
>params.a.key as Key : "my_key"
|
||||
>params.a.key : string
|
||||
>params.a : { key: string; }
|
||||
>params : { a: { key: string; }; }
|
||||
>a : { key: string; }
|
||||
>key : string
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
foo() {
|
||||
>foo : () => void
|
||||
|
||||
const x = !!true;
|
||||
>x : true
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
if (x) {
|
||||
>x : true
|
||||
|
||||
type T0 = typeof this;
|
||||
>T0 : this
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
tests/cases/compiler/thisInTypeQuery.ts
Normal file
32
tests/cases/compiler/thisInTypeQuery.ts
Normal file
@ -0,0 +1,32 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// Repros from #52672
|
||||
|
||||
function assert(condition: unknown): asserts condition {
|
||||
if (!condition) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
private map = {
|
||||
my_key: 'example_value'
|
||||
};
|
||||
|
||||
runTypeFails() {
|
||||
const params = null as any as { a: { key: string } } | null;
|
||||
assert(params);
|
||||
type Key = keyof typeof this.map;
|
||||
this.map[params.a.key as Key];
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
foo() {
|
||||
const x = !!true;
|
||||
if (x) {
|
||||
type T0 = typeof this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user