Fixed crash in hasVisibleDeclarations related to binding elements (#61352)

This commit is contained in:
Mateusz Burzyński 2025-06-30 20:57:47 +02:00 committed by GitHub
parent c33f83ac9b
commit 2ea2ecfdc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 187 additions and 1 deletions

View File

@ -5981,7 +5981,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return addVisibleAlias(declaration, declaration.parent.parent.parent.parent);
}
else if (symbol.flags & SymbolFlags.BlockScopedVariable) {
const variableStatement = findAncestor(declaration, isVariableStatement)!;
const rootDeclaration = walkUpBindingElementsAndPatterns(declaration);
if (rootDeclaration.kind === SyntaxKind.Parameter) {
return false;
}
const variableStatement = rootDeclaration.parent.parent;
if (variableStatement.kind !== SyntaxKind.VariableStatement) {
return false;
}
if (hasSyntacticModifier(variableStatement, ModifierFlags.Export)) {
return true;
}

View File

@ -0,0 +1,28 @@
computedPropertyBindingElementDeclarationNoCrash1.ts(12,21): error TS2345: Argument of type '{ [x: string]: unknown; }' is not assignable to parameter of type 'State'.
Type '{ [x: string]: unknown; }' is missing the following properties from type 'State': a, b
==== computedPropertyBindingElementDeclarationNoCrash1.ts (1 errors) ====
// https://github.com/microsoft/TypeScript/issues/61351
export type State = {
a: number;
b: string;
};
export class Test {
setState(state: State) {}
test = (e: any) => {
for (const [key, value] of Object.entries(e)) {
this.setState({
~
[key]: value,
~~~~~~~~~~~~~~~~~~~~~
});
~~~~~~~
!!! error TS2345: Argument of type '{ [x: string]: unknown; }' is not assignable to parameter of type 'State'.
!!! error TS2345: Type '{ [x: string]: unknown; }' is missing the following properties from type 'State': a, b
}
};
}

View File

@ -0,0 +1,51 @@
//// [tests/cases/compiler/computedPropertyBindingElementDeclarationNoCrash1.ts] ////
=== computedPropertyBindingElementDeclarationNoCrash1.ts ===
// https://github.com/microsoft/TypeScript/issues/61351
export type State = {
>State : Symbol(State, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 0, 0))
a: number;
>a : Symbol(a, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 2, 21))
b: string;
>b : Symbol(b, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 3, 12))
};
export class Test {
>Test : Symbol(Test, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 5, 2))
setState(state: State) {}
>setState : Symbol(Test.setState, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 7, 19))
>state : Symbol(state, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 8, 11))
>State : Symbol(State, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 0, 0))
test = (e: any) => {
>test : Symbol(Test.test, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 8, 27))
>e : Symbol(e, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 9, 10))
for (const [key, value] of Object.entries(e)) {
>key : Symbol(key, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 10, 16))
>value : Symbol(value, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 10, 20))
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
>e : Symbol(e, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 9, 10))
this.setState({
>this.setState : Symbol(Test.setState, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 7, 19))
>this : Symbol(Test, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 5, 2))
>setState : Symbol(Test.setState, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 7, 19))
[key]: value,
>[key] : Symbol([key], Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 11, 21))
>key : Symbol(key, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 10, 16))
>value : Symbol(value, Decl(computedPropertyBindingElementDeclarationNoCrash1.ts, 10, 20))
});
}
};
}

View File

@ -0,0 +1,78 @@
//// [tests/cases/compiler/computedPropertyBindingElementDeclarationNoCrash1.ts] ////
=== computedPropertyBindingElementDeclarationNoCrash1.ts ===
// https://github.com/microsoft/TypeScript/issues/61351
export type State = {
>State : State
> : ^^^^^
a: number;
>a : number
> : ^^^^^^
b: string;
>b : string
> : ^^^^^^
};
export class Test {
>Test : Test
> : ^^^^
setState(state: State) {}
>setState : (state: State) => void
> : ^ ^^ ^^^^^^^^^
>state : State
> : ^^^^^
test = (e: any) => {
>test : (e: any) => void
> : ^ ^^ ^^^^^^^^^
>(e: any) => { for (const [key, value] of Object.entries(e)) { this.setState({ [key]: value, }); } } : (e: any) => void
> : ^ ^^ ^^^^^^^^^
>e : any
> : ^^^
for (const [key, value] of Object.entries(e)) {
>key : string
> : ^^^^^^
>value : unknown
> : ^^^^^^^
>Object.entries(e) : [string, unknown][]
> : ^^^^^^^^^^^^^^^^^^^
>Object.entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^
>Object : ObjectConstructor
> : ^^^^^^^^^^^^^^^^^
>entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^
>e : any
> : ^^^
this.setState({
>this.setState({ [key]: value, }) : void
> : ^^^^
>this.setState : (state: State) => void
> : ^ ^^ ^^^^^^^^^
>this : this
> : ^^^^
>setState : (state: State) => void
> : ^ ^^ ^^^^^^^^^
>{ [key]: value, } : { [x: string]: unknown; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
[key]: value,
>[key] : unknown
> : ^^^^^^^
>key : string
> : ^^^^^^
>value : unknown
> : ^^^^^^^
});
}
};
}

View File

@ -0,0 +1,22 @@
// @strict: true
// @target: esnext
// @lib: esnext
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/61351
export type State = {
a: number;
b: string;
};
export class Test {
setState(state: State) {}
test = (e: any) => {
for (const [key, value] of Object.entries(e)) {
this.setState({
[key]: value,
});
}
};
}