From 728064dd884cf648da1dcbcae5bd72bb62298a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 17 Jan 2026 20:59:11 +0100 Subject: [PATCH 1/3] Don't try to narrow type of a symbol within RHS of its declaration --- src/compiler/checker.ts | 2 +- ...riablesRefereinceInDeclaration1.errors.txt | 93 ++++++++ ...dVariablesRefereinceInDeclaration1.symbols | 118 ++++++++++ ...redVariablesRefereinceInDeclaration1.types | 205 ++++++++++++++++++ ...cturedVariablesRefereinceInDeclaration1.ts | 49 +++++ 5 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt create mode 100644 tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols create mode 100644 tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types create mode 100644 tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts 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; +} From ba0d77c992ab60e0c5e90df4950bbe42af7de0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 19 Jan 2026 09:29:36 +0100 Subject: [PATCH 2/3] Get rid of `NodeCheckFlags.InCheckIdentifier` --- src/compiler/checker.ts | 27 +++++++++++---------------- src/compiler/types.ts | 3 +-- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0d348d092f08a..22e157ab2f0df 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30866,23 +30866,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const parent = declaration.parent.parent; const rootDeclaration = getRootDeclaration(parent); if (rootDeclaration.kind === SyntaxKind.VariableDeclaration && getCombinedNodeFlagsCached(rootDeclaration) & NodeFlags.Constant || rootDeclaration.kind === SyntaxKind.Parameter) { - const links = getNodeLinks(parent); - if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) { - links.flags |= NodeCheckFlags.InCheckIdentifier; - const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal); - const parentTypeConstraint = parentType && mapType(parentType, getBaseConstraintOrType); - links.flags &= ~NodeCheckFlags.InCheckIdentifier; - if (parentTypeConstraint && parentTypeConstraint.flags & TypeFlags.Union && !(rootDeclaration.kind === SyntaxKind.Parameter && isSomeSymbolAssigned(rootDeclaration))) { - const pattern = declaration.parent; - const narrowedType = getFlowTypeOfReference(pattern, parentTypeConstraint, parentTypeConstraint, /*flowContainer*/ undefined, location.flowNode); - if (narrowedType.flags & TypeFlags.Never) { - return neverType; - } - // Destructurings are validated against the parent type elsewhere. Here we disable tuple bounds - // checks because the narrowed type may have lower arity than the full parent type. For example, - // for the declaration [x, y]: [1, 2] | [3], we may have narrowed the parent type to just [3]. - return getBindingElementTypeFromParentType(declaration, narrowedType, /*noTupleBoundsCheck*/ true); + const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal); + const parentTypeConstraint = parentType && mapType(parentType, getBaseConstraintOrType); + if (parentTypeConstraint && parentTypeConstraint.flags & TypeFlags.Union && !(rootDeclaration.kind === SyntaxKind.Parameter && isSomeSymbolAssigned(rootDeclaration))) { + const pattern = declaration.parent; + const narrowedType = getFlowTypeOfReference(pattern, parentTypeConstraint, parentTypeConstraint, /*flowContainer*/ undefined, location.flowNode); + if (narrowedType.flags & TypeFlags.Never) { + return neverType; } + // Destructurings are validated against the parent type elsewhere. Here we disable tuple bounds + // checks because the narrowed type may have lower arity than the full parent type. For example, + // for the declaration [x, y]: [1, 2] | [3], we may have narrowed the parent type to just [3]. + return getBindingElementTypeFromParentType(declaration, narrowedType, /*noTupleBoundsCheck*/ true); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4e9f872720d79..c089c3a87319b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6240,8 +6240,7 @@ export const enum NodeCheckFlags { ConstructorReference = 1 << 29, // Binding to a class constructor inside of the class's body. ContainsClassWithPrivateIdentifiers = 1 << 20, // Marked on all block-scoped containers containing a class with private identifiers. ContainsSuperPropertyInStaticInitializer = 1 << 21, // Marked on all block-scoped containers containing a static initializer with 'super.x' or 'super[x]'. - InCheckIdentifier = 1 << 22, - PartiallyTypeChecked = 1 << 23, // Node has been partially type checked + PartiallyTypeChecked = 1 << 22, // Node has been partially type checked /** These flags are LazyNodeCheckFlags and can be calculated lazily by `hasNodeCheckFlag` */ LazyFlags = SuperInstance From 878c6b237b7773bcb5a1ca4d6f1d98a720240f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 19 Jan 2026 11:15:49 +0100 Subject: [PATCH 3/3] add tests --- ...riablesRefereinceInDeclaration1.errors.txt | 65 +++++++++- ...dVariablesRefereinceInDeclaration1.symbols | 116 +++++++++++++----- ...redVariablesRefereinceInDeclaration1.types | 115 +++++++++++++++++ ...cturedVariablesRefereinceInDeclaration1.ts | 20 +++ 4 files changed, 281 insertions(+), 35 deletions(-) diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt index dbc8acc6b4c5b..52b1694956502 100644 --- a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.errors.txt @@ -10,11 +10,23 @@ dependentDestructuredVariablesRefereinceInDeclaration1.ts(14,9): error TS2322: T 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(20,9): error TS2322: Type '{ c: number; f: number; }' is not assignable to type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,11): error TS2339: Property 'c' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,14): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,14): error TS2451: Cannot redeclare block-scoped variable 'f'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,17): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,17): error TS2451: Cannot redeclare block-scoped variable 'f'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(25,9): error TS2322: Type '{ c: number; f: number; }' is not assignable to type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(25,11): error TS2339: Property 'c' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(25,14): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(25,17): error TS2339: Property 'f' does not exist on type 'string | number'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(30,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(30,71): error TS2448: Block-scoped variable 'f' used before its declaration. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(58,14): error TS2451: Cannot redeclare block-scoped variable 'f'. +dependentDestructuredVariablesRefereinceInDeclaration1.ts(58,17): error TS2451: Cannot redeclare block-scoped variable 'f'. -==== dependentDestructuredVariablesRefereinceInDeclaration1.ts (14 errors) ==== +==== dependentDestructuredVariablesRefereinceInDeclaration1.ts (26 errors) ==== // https://github.com/microsoft/TypeScript/issues/62993 { @@ -58,13 +70,43 @@ dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,71): error TS2448: g; } + { + const { c, f, f }: string | number = { c: 0, f: 0 }; + ~~~~~~~~~~~ +!!! error TS2322: Type '{ c: number; f: 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 TS2451: Cannot redeclare block-scoped variable 'f'. + ~ +!!! error TS2339: Property 'f' does not exist on type 'string | number'. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'f'. + f; + } + + { + const { c, f, f: g }: string | number = { c: 0, f: 0 }; + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ c: number; f: 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 'f' does not exist on type 'string | number'. + 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. +!!! related TS2728 dependentDestructuredVariablesRefereinceInDeclaration1.ts:30:14: 'f' is declared here. f; } @@ -90,4 +132,17 @@ dependentDestructuredVariablesRefereinceInDeclaration1.ts(20,71): error TS2448: f; g; } - \ No newline at end of file + + { + const { c, f, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'f'. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'f'. + f; + } + + { + const { c, f, f: g }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; + g; + } \ No newline at end of file diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols index a42f22fdad78d..50588fd7598ce 100644 --- a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.symbols @@ -44,75 +44,131 @@ } { - const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; + const { c, f, f }: string | number = { c: 0, f: 0 }; >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 : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 15)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 40)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 46)) f; >f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 19, 12)) } { - const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { + const { c, f, f: g }: string | number = { c: 0, f: 0 }; >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)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 15)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 43)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 49)) + + g; +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 15)) +} + +{ + const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 19)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 25)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 41)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 47)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 63)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 69)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 29, 12)) +} + +{ + const { c, f }: { c: 0; f: () => unknown } | { c: 1; f: string } = { +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 12)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 19)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 25)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 48)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 54)) c: 0, ->c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 70)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 70)) f: () => f, ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 25, 9)) ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 12)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 35, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 12)) }; f; ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 24, 12)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 12)) } { const { c, ->c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 32, 9)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 42, 9)) f, ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 43, 6)) g = f, ->g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 6)) ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 44, 6)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 43, 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 : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 47, 7)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 47, 13)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 47, 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 : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 48, 7)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 48, 13)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 48, 24)) c: 0, ->c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 38, 40)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 48, 40)) f: 10n, ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 39, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 49, 9)) }; f; ->f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 33, 6)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 43, 6)) g; ->g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 34, 6)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 44, 6)) +} + +{ + const { c, f, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 12)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 15)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 22)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 28)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 44)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 50)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 66)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 72)) + + f; +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 57, 12)) } +{ + const { c, f, f: g }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 9)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 12)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 31), Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 53)) +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 15)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 25)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 31)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 47)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 53)) +>c : Symbol(c, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 69)) +>f : Symbol(f, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 75)) + + g; +>g : Symbol(g, Decl(dependentDestructuredVariablesRefereinceInDeclaration1.ts, 62, 15)) +} diff --git a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types index 17794489a97d0..2bad97d739b97 100644 --- a/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types +++ b/tests/baselines/reference/dependentDestructuredVariablesRefereinceInDeclaration1.types @@ -81,6 +81,56 @@ > : ^^^ } +{ + const { c, f, f }: string | number = { c: 0, f: 0 }; +>c : any +> : ^^^ +>f : any +> : ^^^ +>f : any +> : ^^^ +>{ c: 0, f: 0 } : { c: number; f: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>c : number +> : ^^^^^^ +>0 : 0 +> : ^ +>f : number +> : ^^^^^^ +>0 : 0 +> : ^ + + f; +>f : any +> : ^^^ +} + +{ + const { c, f, f: g }: string | number = { c: 0, f: 0 }; +>c : any +> : ^^^ +>f : any +> : ^^^ +>f : any +> : ^^^ +>g : any +> : ^^^ +>{ c: 0, f: 0 } : { c: number; f: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>c : number +> : ^^^^^^ +>0 : 0 +> : ^ +>f : number +> : ^^^^^^ +>0 : 0 +> : ^ + + g; +>g : any +> : ^^^ +} + { const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; >c : 0 | 1 @@ -203,3 +253,68 @@ > : ^^^^^^^^^^^^^^^^^^^^^^^^ } +{ + const { c, f, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; +>c : 0 | 1 +> : ^^^^^ +>f : string | number +> : ^^^^^^^^^^^^^^^ +>f : string | number +> : ^^^^^^^^^^^^^^^ +>c : 0 +> : ^ +>f : number +> : ^^^^^^ +>c : 1 +> : ^ +>f : string +> : ^^^^^^ +>{ c: 0, f: 0 } : { c: 0; f: number; } +> : ^^^^^^^^^^^^^^^^^^^^ +>c : 0 +> : ^ +>0 : 0 +> : ^ +>f : number +> : ^^^^^^ +>0 : 0 +> : ^ + + f; +>f : number +> : ^^^^^^ +} + +{ + const { c, f, f: g }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; +>c : 0 | 1 +> : ^^^^^ +>f : string | number +> : ^^^^^^^^^^^^^^^ +>f : any +> : ^^^ +>g : string | number +> : ^^^^^^^^^^^^^^^ +>c : 0 +> : ^ +>f : number +> : ^^^^^^ +>c : 1 +> : ^ +>f : string +> : ^^^^^^ +>{ c: 0, f: 0 } : { c: 0; f: number; } +> : ^^^^^^^^^^^^^^^^^^^^ +>c : 0 +> : ^ +>0 : 0 +> : ^ +>f : number +> : ^^^^^^ +>0 : 0 +> : ^ + + g; +>g : number +> : ^^^^^^ +} diff --git a/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts b/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts index 0e62c895292d3..9df85955b43ce 100644 --- a/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts +++ b/tests/cases/conformance/controlFlow/dependentDestructuredVariablesRefereinceInDeclaration1.ts @@ -20,6 +20,16 @@ g; } +{ + const { c, f, f }: string | number = { c: 0, f: 0 }; + f; +} + +{ + const { c, f, f: g }: string | number = { c: 0, f: 0 }; + g; +} + { const { c, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f }; f; @@ -47,3 +57,13 @@ f; g; } + +{ + const { c, f, f }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; + f; +} + +{ + const { c, f, f: g }: { c: 0; f: number } | { c: 1; f: string } = { c: 0, f: 0 }; + g; +} \ No newline at end of file