diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 390c843b0c968..0d348d092f08a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30838,7 +30838,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier) { const type = getTypeOfSymbol(symbol); const declaration = symbol.valueDeclaration; - if (declaration) { + if (declaration && !textRangeContainsPositionInclusive(getRootDeclaration(declaration), location.pos)) { // If we have a non-rest binding element with no initializer declared as a const variable or a const-like // parameter (a parameter for which there are no assignments in the function body), and if the parent type // for the destructuring is a union type, one or more of the binding elements may represent discriminant diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt new file mode 100644 index 0000000000000..dbc8acc6b4c5b --- /dev/null +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt @@ -0,0 +1,93 @@ +dependentDestructuredVariablesRefereinceInDeclaration1.ts(4,9): error TS2322: Type '{ c: number; f: any; }' is not assignable to type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(4,11): error TS2339: Property 'c' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(4,14): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(4,14): error TS7022: 'f' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(4,45): error TS2448: Block-scoped variable 'f' used before its declaration. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(9,9): error TS2322: Type '{ c: number; f: () => any; }' is not assignable to type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(9,11): error TS2339: Property 'c' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(9,14): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(14,9): error TS2322: Type '{ c: number; f: number; g: number; }' is not assignable to type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(14,11): error TS2339: Property 'c' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(14,14): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(14,17): error TS2339: Property 'g' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,14): error TS7022: 'f' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,71): error TS2448: Block-scoped variable 'f' used before its declaration. + + +==== dependentDestructuredVariablesRefereinceInDeclaration1.ts (14 errors) ==== + // https://github.com/microsoft/TypeScript/issues/62993 + + { + const { c, f }: string | number = { c: 0, f }; + ~~~~~~~~ +!!! error TS2322: Type '{ c: number; f: any; }' is not assignable to type 'string | number'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'string | number'. + ~ +!!! error TS2339: Property 'f' does not exist on type 'string | number'. + ~ +!!! error TS7022: 'f' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ~ +!!! error TS2448: Block-scoped variable 'f' used before its declaration. +!!! related TS2728 dependentDestructuredVariablesRefereinceInDeclaration1.ts:4:14: 'f' is declared here. + f; + } + + { + const { c, f }: string | number = { c: 0, f: () => f }; + ~~~~~~~~ +!!! error TS2322: Type '{ c: number; f: () => any; }' is not assignable to type 'string | number'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'string | number'. + ~ +!!! error TS2339: Property 'f' does not exist on type 'string | number'. + f; + } + + { + const { c, f, g = f }: string | number = { c: 0, f: 0, g: 0 }; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ c: number; f: number; g: number; }' is not assignable to type 'string | number'. + ~ +!!! error TS2339: Property 'c' does not exist on type 'string | number'. + ~ +!!! error TS2339: Property 'f' does not exist on type 'string | number'. + ~ +!!! error TS2339: Property 'g' does not exist on type 'string | number'. + f; + g; + } + + { + const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; + ~ +!!! error TS7022: 'f' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. + ~ +!!! error TS2448: Block-scoped variable 'f' used before its declaration. +!!! related TS2728 dependentDestructuredVariablesRefereinceInDeclaration1.ts:20:14: 'f' is declared here. + f; + } + + { + const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { + c: 0, + f: () => f, + }; + f; + } + + { + const { + c, + f, + g = f, + }: + | { c: 0; f: bigint; g?: bigint | number } + | { c: 1; f: number; g: string } = { + c: 0, + f: 10n, + }; + f; + g; + } + \ No newline at end of file diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols new file mode 100644 index 0000000000000..a42f22fdad78d --- /dev/null +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols @@ -0,0 +1,118 @@ +//// [tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts] //// + +=== dependentDestructuredVariablesRefereinceInDeclaration1.ts === +// https://github.com/microsoft/TypeScript/issues/62993 + +{ + const { c, f }: string | number = { c: 0, f }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 3, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 3, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 3, 37)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 3, 43)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 3, 12)) +} + +{ + const { c, f }: string | number = { c: 0, f: () => f }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 37)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 43)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 12)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 8, 12)) +} + +{ + const { c, f, g = f }: string | number = { c: 0, f: 0, g: 0 }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 12)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 15)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 44)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 50)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 56)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 12)) + + g; +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 13, 15)) +} + +{ + const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 19)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 25)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 41)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 47)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 63)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 69)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 12)) +} + +{ + const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 19)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 25)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 48)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 54)) + + c: 0, +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 70)) + + f: () => f, +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 25, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 12)) + + }; + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 12)) +} + +{ + const { + c, +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 32, 9)) + + f, +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) + + g = f, +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 6)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) + + }: + | { c: 0; f: bigint; g?: bigint | number } +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 37, 7)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 37, 13)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 37, 24)) + + | { c: 1; f: number; g: string } = { +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 38, 7)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 38, 13)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 38, 24)) + + c: 0, +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 38, 40)) + + f: 10n, +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 39, 9)) + + }; + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) + + g; +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 6)) +} + diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types new file mode 100644 index 0000000000000..17794489a97d0 --- /dev/null +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types @@ -0,0 +1,205 @@ +//// [tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts] //// + +=== dependentDestructuredVariablesRefereinceInDeclaration1.ts === +// https://github.com/microsoft/TypeScript/issues/62993 + +{ + const { c, f }: string | number = { c: 0, f }; +>c : any +> : ^^^ +>f : any +> : ^^^ +>{ c: 0, f } : { c: number; f: any; } +> : ^^^^^^^^^^^^^^^^^^^^^^ +>c : number +> : ^^^^^^ +>0 : 0 +> : ^ +>f : any +> : ^^^ + + f; +>f : any +> : ^^^ +} + +{ + const { c, f }: string | number = { c: 0, f: () => f }; +>c : any +> : ^^^ +>f : any +> : ^^^ +>{ c: 0, f: () => f } : { c: number; f: () => any; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>c : number +> : ^^^^^^ +>0 : 0 +> : ^ +>f : () => any +> : ^^^^^^^^^ +>() => f : () => any +> : ^^^^^^^^^ +>f : any +> : ^^^ + + f; +>f : any +> : ^^^ +} + +{ + const { c, f, g = f }: string | number = { c: 0, f: 0, g: 0 }; +>c : any +> : ^^^ +>f : any +> : ^^^ +>g : any +> : ^^^ +>f : any +> : ^^^ +>{ c: 0, f: 0, g: 0 } : { c: number; f: number; g: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>c : number +> : ^^^^^^ +>0 : 0 +> : ^ +>f : number +> : ^^^^^^ +>0 : 0 +> : ^ +>g : number +> : ^^^^^^ +>0 : 0 +> : ^ + + f; +>f : any +> : ^^^ + + g; +>g : any +> : ^^^ +} + +{ + const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; +>c : 0 | 1 +> : ^^^^^ +>f : any +> : ^^^ +>c : 0 +> : ^ +>f : number +> : ^^^^^^ +>c : 1 +> : ^ +>f : string +> : ^^^^^^ +>{ c: 0, f } : { c: 0; f: any; } +> : ^^^^^^^^^^^^^^^^^ +>c : 0 +> : ^ +>0 : 0 +> : ^ +>f : any +> : ^^^ + + f; +>f : string | number +> : ^^^^^^^^^^^^^^^ +} + +{ + const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { +>c : 0 | 1 +> : ^^^^^ +>f : string | (() => unknown) +> : ^^^^^^^^^^^^^^^^ ^ +>c : 0 +> : ^ +>f : () => unknown +> : ^^^^^^ +>c : 1 +> : ^ +>f : string +> : ^^^^^^ +>{ c: 0, f: () => f, } : { c: 0; f: () => string | (() => unknown); } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ + + c: 0, +>c : 0 +> : ^ +>0 : 0 +> : ^ + + f: () => f, +>f : () => string | (() => unknown) +> : ^^^^^^^^^^^^^^^^^^^^^^ ^ +>() => f : () => string | (() => unknown) +> : ^^^^^^^^^^^^^^^^^^^^^^ ^ +>f : string | (() => unknown) +> : ^^^^^^^^^^^^^^^^ ^ + + }; + f; +>f : () => unknown +> : ^^^^^^ +} + +{ + const { + c, +>c : 0 | 1 +> : ^^^^^ + + f, +>f : number | bigint +> : ^^^^^^^^^^^^^^^ + + g = f, +>g : string | number | bigint +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>f : number | bigint +> : ^^^^^^^^^^^^^^^ + + }: + | { c: 0; f: bigint; g?: bigint | number } +>c : 0 +> : ^ +>f : bigint +> : ^^^^^^ +>g : number | bigint | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + | { c: 1; f: number; g: string } = { +>c : 1 +> : ^ +>f : number +> : ^^^^^^ +>g : string +> : ^^^^^^ +>{ c: 0, f: 10n, } : { c: 0; f: bigint; } +> : ^^^^^^^^^^^^^^^^^^^^ + + c: 0, +>c : 0 +> : ^ +>0 : 0 +> : ^ + + f: 10n, +>f : bigint +> : ^^^^^^ +>10n : 10n +> : ^^^ + + }; + f; +>f : bigint +> : ^^^^^^ + + g; +>g : string | number | bigint +> : ^^^^^^^^^^^^^^^^^^^^^^^^ +} + diff --git a/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts b/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts new file mode 100644 index 0000000000000..0e62c895292d3 --- /dev/null +++ b/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts @@ -0,0 +1,49 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62993 + +{ + const { c, f }: string | number = { c: 0, f }; + f; +} + +{ + const { c, f }: string | number = { c: 0, f: () => f }; + f; +} + +{ + const { c, f, g = f }: string | number = { c: 0, f: 0, g: 0 }; + f; + g; +} + +{ + const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; + f; +} + +{ + const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { + c: 0, + f: () => f, + }; + f; +} + +{ + const { + c, + f, + g = f, + }: + | { c: 0; f: bigint; g?: bigint | number } + | { c: 1; f: number; g: string } = { + c: 0, + f: 10n, + }; + f; + g; +}