From 28cdebc55f42c7afb3aad44c41b10598bdab99a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 2 Oct 2024 21:23:07 +0200 Subject: [PATCH 1/4] Error on destructured nullables --- src/compiler/checker.ts | 5 +- .../awaitUsingDeclarations.5.errors.txt | 5 +- .../awaitUsingDeclarations.6.errors.txt | 5 +- .../awaitUsingDeclarations.7.errors.txt | 5 +- ...ternCannotBeOnlyInferenceSource.errors.txt | 8 ++- ...PatternWithNullableInitializer1.errors.txt | 32 +++++++++ ...ingPatternWithNullableInitializer1.symbols | 63 +++++++++++++++++ ...ndingPatternWithNullableInitializer1.types | 70 +++++++++++++++++++ ...alizedVariablesFiltersUndefined.errors.txt | 8 ++- ...BindingPatternAndAssignment1ES5.errors.txt | 8 ++- ...atternAndAssignment1ES5iterable.errors.txt | 8 ++- ...BindingPatternAndAssignment1ES6.errors.txt | 8 ++- ...rayBindingPatternAndAssignment2.errors.txt | 5 +- ...rayBindingPatternAndAssignment4.errors.txt | 5 +- ...BindingPatternAndAssignment1ES5.errors.txt | 60 ++++++++++++++++ ...bjectBindingPatternAndAssignment1ES5.types | 1 + ...BindingPatternAndAssignment1ES6.errors.txt | 60 ++++++++++++++++ ...bjectBindingPatternAndAssignment1ES6.types | 1 + ...ectBindingPatternAndAssignment3.errors.txt | 5 +- .../restElementWithNullInitializer.errors.txt | 8 ++- .../restInvalidArgumentType.errors.txt | 8 ++- .../baselines/reference/restUnion2.errors.txt | 18 +++++ .../baselines/reference/restUnion3.errors.txt | 5 +- .../reference/unknownType1.errors.txt | 5 +- .../reference/usingDeclarations.5.errors.txt | 5 +- .../reference/usingDeclarations.6.errors.txt | 5 +- .../reference/usingDeclarations.7.errors.txt | 5 +- .../bindingPatternWithNullableInitializer1.ts | 22 ++++++ 28 files changed, 422 insertions(+), 21 deletions(-) create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer1.types create mode 100644 tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.errors.txt create mode 100644 tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.errors.txt create mode 100644 tests/baselines/reference/restUnion2.errors.txt create mode 100644 tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 88448475aaa67..296ad1ff46abd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44493,12 +44493,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Don't validate for-in initializer as it is already an error const widenedType = getWidenedTypeForVariableLikeDeclaration(node); if (needCheckInitializer) { - const initializerType = checkExpressionCached(node.initializer); if (strictNullChecks && needCheckWidenedType) { - checkNonNullNonVoidType(initializerType, node); + checkNonNullNonVoidType(checkExpressionCached(node.initializer), node); } else { - checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer); + checkTypeAssignableToAndOptionallyElaborate(checkNonNullExpression(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer); } } // check the binding pattern with empty elements diff --git a/tests/baselines/reference/awaitUsingDeclarations.5.errors.txt b/tests/baselines/reference/awaitUsingDeclarations.5.errors.txt index 370cc3a6c7a45..f6e2e7ad6f6ad 100644 --- a/tests/baselines/reference/awaitUsingDeclarations.5.errors.txt +++ b/tests/baselines/reference/awaitUsingDeclarations.5.errors.txt @@ -1,8 +1,9 @@ awaitUsingDeclarations.5.ts(3,17): error TS1492: 'await using' declarations may not have binding patterns. awaitUsingDeclarations.5.ts(3,17): error TS2488: Type 'null' must have a '[Symbol.iterator]()' method that returns an iterator. +awaitUsingDeclarations.5.ts(3,23): error TS18050: The value 'null' cannot be used here. -==== awaitUsingDeclarations.5.ts (2 errors) ==== +==== awaitUsingDeclarations.5.ts (3 errors) ==== { await using a = null, [b] = null, @@ -10,6 +11,8 @@ awaitUsingDeclarations.5.ts(3,17): error TS2488: Type 'null' must have a '[Symbo !!! error TS1492: 'await using' declarations may not have binding patterns. ~~~ !!! error TS2488: Type 'null' must have a '[Symbol.iterator]()' method that returns an iterator. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. c = null; } diff --git a/tests/baselines/reference/awaitUsingDeclarations.6.errors.txt b/tests/baselines/reference/awaitUsingDeclarations.6.errors.txt index 7f471afa221e7..6644a17c59dd4 100644 --- a/tests/baselines/reference/awaitUsingDeclarations.6.errors.txt +++ b/tests/baselines/reference/awaitUsingDeclarations.6.errors.txt @@ -1,14 +1,17 @@ awaitUsingDeclarations.6.ts(2,17): error TS1492: 'await using' declarations may not have binding patterns. awaitUsingDeclarations.6.ts(2,18): error TS2339: Property 'a' does not exist on type 'null'. +awaitUsingDeclarations.6.ts(2,23): error TS18050: The value 'null' cannot be used here. -==== awaitUsingDeclarations.6.ts (2 errors) ==== +==== awaitUsingDeclarations.6.ts (3 errors) ==== { await using {a} = null; ~~~ !!! error TS1492: 'await using' declarations may not have binding patterns. ~ !!! error TS2339: Property 'a' does not exist on type 'null'. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. } diff --git a/tests/baselines/reference/awaitUsingDeclarations.7.errors.txt b/tests/baselines/reference/awaitUsingDeclarations.7.errors.txt index c3061741e4f39..2297de68be1db 100644 --- a/tests/baselines/reference/awaitUsingDeclarations.7.errors.txt +++ b/tests/baselines/reference/awaitUsingDeclarations.7.errors.txt @@ -1,9 +1,10 @@ awaitUsingDeclarations.7.ts(2,5): error TS2853: 'await using' statements are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module. awaitUsingDeclarations.7.ts(3,17): error TS1492: 'await using' declarations may not have binding patterns. awaitUsingDeclarations.7.ts(3,18): error TS2339: Property 'b' does not exist on type 'null'. +awaitUsingDeclarations.7.ts(3,23): error TS18050: The value 'null' cannot be used here. -==== awaitUsingDeclarations.7.ts (3 errors) ==== +==== awaitUsingDeclarations.7.ts (4 errors) ==== { await using a = null, ~~~~~ @@ -13,5 +14,7 @@ awaitUsingDeclarations.7.ts(3,18): error TS2339: Property 'b' does not exist on !!! error TS1492: 'await using' declarations may not have binding patterns. ~ !!! error TS2339: Property 'b' does not exist on type 'null'. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. c = null; } \ No newline at end of file diff --git a/tests/baselines/reference/bindingPatternCannotBeOnlyInferenceSource.errors.txt b/tests/baselines/reference/bindingPatternCannotBeOnlyInferenceSource.errors.txt index b4237742ac51d..3adb1d9771864 100644 --- a/tests/baselines/reference/bindingPatternCannotBeOnlyInferenceSource.errors.txt +++ b/tests/baselines/reference/bindingPatternCannotBeOnlyInferenceSource.errors.txt @@ -1,11 +1,13 @@ bindingPatternCannotBeOnlyInferenceSource.ts(2,7): error TS2571: Object is of type 'unknown'. bindingPatternCannotBeOnlyInferenceSource.ts(3,9): error TS2339: Property 'p1' does not exist on type 'unknown'. +bindingPatternCannotBeOnlyInferenceSource.ts(3,16): error TS2571: Object is of type 'unknown'. bindingPatternCannotBeOnlyInferenceSource.ts(4,7): error TS2461: Type 'unknown' is not an array type. bindingPatternCannotBeOnlyInferenceSource.ts(4,7): error TS2571: Object is of type 'unknown'. bindingPatternCannotBeOnlyInferenceSource.ts(5,7): error TS2461: Type 'unknown' is not an array type. +bindingPatternCannotBeOnlyInferenceSource.ts(5,18): error TS2571: Object is of type 'unknown'. -==== bindingPatternCannotBeOnlyInferenceSource.ts (5 errors) ==== +==== bindingPatternCannotBeOnlyInferenceSource.ts (7 errors) ==== declare function f(): T; const {} = f(); // error (only in strictNullChecks) ~~ @@ -13,6 +15,8 @@ bindingPatternCannotBeOnlyInferenceSource.ts(5,7): error TS2461: Type 'unknown' const { p1 } = f(); // error ~~ !!! error TS2339: Property 'p1' does not exist on type 'unknown'. + ~~~ +!!! error TS2571: Object is of type 'unknown'. const [] = f(); // error ~~ !!! error TS2461: Type 'unknown' is not an array type. @@ -21,6 +25,8 @@ bindingPatternCannotBeOnlyInferenceSource.ts(5,7): error TS2461: Type 'unknown' const [e1, e2] = f(); // error ~~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~ +!!! error TS2571: Object is of type 'unknown'. // Repro from #43605 type Dispatch = { (action: T): T }; diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt new file mode 100644 index 0000000000000..a914cb1c3895e --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt @@ -0,0 +1,32 @@ +bindingPatternWithNullableInitializer1.ts(10,22): error TS18048: 't' is possibly 'undefined'. +bindingPatternWithNullableInitializer1.ts(14,22): error TS18047: 't' is possibly 'null'. +bindingPatternWithNullableInitializer1.ts(18,22): error TS18049: 't' is possibly 'null' or 'undefined'. + + +==== bindingPatternWithNullableInitializer1.ts (3 errors) ==== + // https://github.com/microsoft/TypeScript/issues/60119 + + interface T { + a?: unknown; + b?: unknown; + c?: unknown; + } + + function f1(k: L, t: T | undefined) { + const { [k]: v } = t; + ~ +!!! error TS18048: 't' is possibly 'undefined'. + } + + function f2(k: L, t: T | null) { + const { [k]: v } = t; + ~ +!!! error TS18047: 't' is possibly 'null'. + } + + function f3(k: L, t: T | null | undefined) { + const { [k]: v } = t; + ~ +!!! error TS18049: 't' is possibly 'null' or 'undefined'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols new file mode 100644 index 0000000000000..3cc6d53ed1757 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols @@ -0,0 +1,63 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts] //// + +=== bindingPatternWithNullableInitializer1.ts === +// https://github.com/microsoft/TypeScript/issues/60119 + +interface T { +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) + + a?: unknown; +>a : Symbol(T.a, Decl(bindingPatternWithNullableInitializer1.ts, 2, 13)) + + b?: unknown; +>b : Symbol(T.b, Decl(bindingPatternWithNullableInitializer1.ts, 3, 14)) + + c?: unknown; +>c : Symbol(T.c, Decl(bindingPatternWithNullableInitializer1.ts, 4, 14)) +} + +function f1(k: L, t: T | undefined) { +>f1 : Symbol(f1, Decl(bindingPatternWithNullableInitializer1.ts, 6, 1)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 8, 12)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 8, 31)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 8, 12)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 8, 36)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) + + const { [k]: v } = t; +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 8, 31)) +>v : Symbol(v, Decl(bindingPatternWithNullableInitializer1.ts, 9, 9)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 8, 36)) +} + +function f2(k: L, t: T | null) { +>f2 : Symbol(f2, Decl(bindingPatternWithNullableInitializer1.ts, 10, 1)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 12, 12)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 12, 31)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 12, 12)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 12, 36)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) + + const { [k]: v } = t; +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 12, 31)) +>v : Symbol(v, Decl(bindingPatternWithNullableInitializer1.ts, 13, 9)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 12, 36)) +} + +function f3(k: L, t: T | null | undefined) { +>f3 : Symbol(f3, Decl(bindingPatternWithNullableInitializer1.ts, 14, 1)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 16, 12)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 16, 31)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 16, 12)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 16, 36)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) + + const { [k]: v } = t; +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 16, 31)) +>v : Symbol(v, Decl(bindingPatternWithNullableInitializer1.ts, 17, 9)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 16, 36)) +} + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.types b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types new file mode 100644 index 0000000000000..f804ae1730855 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types @@ -0,0 +1,70 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts] //// + +=== bindingPatternWithNullableInitializer1.ts === +// https://github.com/microsoft/TypeScript/issues/60119 + +interface T { + a?: unknown; +>a : unknown +> : ^^^^^^^ + + b?: unknown; +>b : unknown +> : ^^^^^^^ + + c?: unknown; +>c : unknown +> : ^^^^^^^ +} + +function f1(k: L, t: T | undefined) { +>f1 : (k: L, t: T | undefined) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ +>k : L +> : ^ +>t : T | undefined +> : ^^^^^^^^^^^^^ + + const { [k]: v } = t; +>k : L +> : ^ +>v : (T | undefined)[L] +> : ^^^^^^^^^^^^^^^^^^ +>t : T | undefined +> : ^^^^^^^^^^^^^ +} + +function f2(k: L, t: T | null) { +>f2 : (k: L, t: T | null) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ +>k : L +> : ^ +>t : T | null +> : ^^^^^^^^ + + const { [k]: v } = t; +>k : L +> : ^ +>v : (T | null)[L] +> : ^^^^^^^^^^^^^ +>t : T | null +> : ^^^^^^^^ +} + +function f3(k: L, t: T | null | undefined) { +>f3 : (k: L, t: T | null | undefined) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ +>k : L +> : ^ +>t : T | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^ + + const { [k]: v } = t; +>k : L +> : ^ +>v : (T | null | undefined)[L] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>t : T | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^ +} + diff --git a/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.errors.txt b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.errors.txt index c869ec94fbb55..8beba96718a50 100644 --- a/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.errors.txt +++ b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.errors.txt @@ -1,8 +1,10 @@ contextualTypeForInitalizedVariablesFiltersUndefined.ts(7,9): error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'. +contextualTypeForInitalizedVariablesFiltersUndefined.ts(7,15): error TS18048: 't' is possibly 'undefined'. contextualTypeForInitalizedVariablesFiltersUndefined.ts(8,16): error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'. +contextualTypeForInitalizedVariablesFiltersUndefined.ts(8,22): error TS18048: 't' is possibly 'undefined'. -==== contextualTypeForInitalizedVariablesFiltersUndefined.ts (2 errors) ==== +==== contextualTypeForInitalizedVariablesFiltersUndefined.ts (4 errors) ==== const fInferred = ({ a = 0 } = {}) => a; // const fInferred: ({ a }?: { a?: number; }) => number @@ -12,7 +14,11 @@ contextualTypeForInitalizedVariablesFiltersUndefined.ts(8,16): error TS2339: Pro const { s } = t; ~ !!! error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'. + ~ +!!! error TS18048: 't' is possibly 'undefined'. function fst({ s } = t) { } ~ !!! error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'. + ~ +!!! error TS18048: 't' is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt index 6a57abba2c006..3ba94593af1e9 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.errors.txt @@ -1,9 +1,11 @@ +destructuringArrayBindingPatternAndAssignment1ES5.ts(24,21): error TS18050: The value 'undefined' cannot be used here. +destructuringArrayBindingPatternAndAssignment1ES5.ts(25,33): error TS18050: The value 'undefined' cannot be used here. destructuringArrayBindingPatternAndAssignment1ES5.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES5.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES5.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. -==== destructuringArrayBindingPatternAndAssignment1ES5.ts (3 errors) ==== +==== destructuringArrayBindingPatternAndAssignment1ES5.ts (5 errors) ==== /* AssignmentPattern: * ObjectAssignmentPattern * ArrayAssignmentPattern @@ -28,7 +30,11 @@ destructuringArrayBindingPatternAndAssignment1ES5.ts(44,18): error TS2493: Tuple // S is the type Any, or var [a0, a1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. var [a2 = false, a3 = 1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is a tuple- like type (section 3.3.3) with a property named N of a type that is assignable to the target given in E, diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt index 991b50d74ccc4..e1a5dce1d770a 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5iterable.errors.txt @@ -1,9 +1,11 @@ +destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(24,21): error TS18050: The value 'undefined' cannot be used here. +destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(25,33): error TS18050: The value 'undefined' cannot be used here. destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. -==== destructuringArrayBindingPatternAndAssignment1ES5iterable.ts (3 errors) ==== +==== destructuringArrayBindingPatternAndAssignment1ES5iterable.ts (5 errors) ==== /* AssignmentPattern: * ObjectAssignmentPattern * ArrayAssignmentPattern @@ -28,7 +30,11 @@ destructuringArrayBindingPatternAndAssignment1ES5iterable.ts(44,18): error TS249 // S is the type Any, or var [a0, a1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. var [a2 = false, a3 = 1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is a tuple- like type (section 3.3.3) with a property named N of a type that is assignable to the target given in E, diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt index 064aba8a011ba..124e36d5dfb9e 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES6.errors.txt @@ -1,9 +1,11 @@ +destructuringArrayBindingPatternAndAssignment1ES6.ts(24,21): error TS18050: The value 'undefined' cannot be used here. +destructuringArrayBindingPatternAndAssignment1ES6.ts(25,33): error TS18050: The value 'undefined' cannot be used here. destructuringArrayBindingPatternAndAssignment1ES6.ts(43,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES6.ts(44,8): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. destructuringArrayBindingPatternAndAssignment1ES6.ts(44,18): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. -==== destructuringArrayBindingPatternAndAssignment1ES6.ts (3 errors) ==== +==== destructuringArrayBindingPatternAndAssignment1ES6.ts (5 errors) ==== /* AssignmentPattern: * ObjectAssignmentPattern * ArrayAssignmentPattern @@ -28,7 +30,11 @@ destructuringArrayBindingPatternAndAssignment1ES6.ts(44,18): error TS2493: Tuple // S is the type Any, or var [a0, a1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. var [a2 = false, a3 = 1]: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is a tuple- like type (section 3.3.3) with a property named N of a type that is assignable to the target given in E, diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index b6e5cba86d173..8a3cf1159ae43 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -3,6 +3,7 @@ destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2493: Tuple type destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2461: Type 'undefined' is not an array type. destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. +destructuringArrayBindingPatternAndAssignment2.ts(4,22): error TS18050: The value 'undefined' cannot be used here. destructuringArrayBindingPatternAndAssignment2.ts(9,51): error TS2322: Type 'number' is not assignable to type 'boolean'. destructuringArrayBindingPatternAndAssignment2.ts(22,5): error TS2322: Type 'number[]' is not assignable to type '[number, number]'. Target requires 2 element(s) but source may have fewer. @@ -11,7 +12,7 @@ destructuringArrayBindingPatternAndAssignment2.ts(23,5): error TS2322: Type 'num destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' is not an array type. -==== destructuringArrayBindingPatternAndAssignment2.ts (9 errors) ==== +==== destructuringArrayBindingPatternAndAssignment2.ts (10 errors) ==== // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is the type Any, or var [[a0], [[a1]]] = [] // Error @@ -26,6 +27,8 @@ destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' var [[a2], [[a3]]] = undefined // Error ~~~~~~~~~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is a tuple- like type (section 3.3.3) with a property named N of a type that is assignable to the target given in E, diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment4.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment4.errors.txt index ea3ee538ee477..84062afaa17e6 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment4.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment4.errors.txt @@ -1,7 +1,8 @@ destructuringArrayBindingPatternAndAssignment4.ts(5,7): error TS2548: Type 'number[] | null' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. +destructuringArrayBindingPatternAndAssignment4.ts(5,17): error TS18047: 'data' is possibly 'null'. -==== destructuringArrayBindingPatternAndAssignment4.ts (1 errors) ==== +==== destructuringArrayBindingPatternAndAssignment4.ts (2 errors) ==== // #35497 @@ -9,4 +10,6 @@ destructuringArrayBindingPatternAndAssignment4.ts(5,7): error TS2548: Type 'numb const [value] = data; // Error ~~~~~~~ !!! error TS2548: Type 'number[] | null' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. + ~~~~ +!!! error TS18047: 'data' is possibly 'null'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.errors.txt b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.errors.txt new file mode 100644 index 0000000000000..b58529c6aed1f --- /dev/null +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.errors.txt @@ -0,0 +1,60 @@ +destructuringObjectBindingPatternAndAssignment1ES5.ts(6,19): error TS18050: The value 'undefined' cannot be used here. + + +==== destructuringObjectBindingPatternAndAssignment1ES5.ts (1 errors) ==== + // In a destructuring assignment expression, the type of the expression on the right must be assignable to the assignment target on the left. + // An expression of type S is considered assignable to an assignment target V if one of the following is true + + // V is an object assignment pattern and, for each assignment property P in V, + // S is the type Any, or + var { a1 }: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. + var { a2 }: any = {}; + + // V is an object assignment pattern and, for each assignment property P in V, + // S has an apparent property with the property name specified in + // P of a type that is assignable to the target given in P, or + var { b1, } = { b1:1, }; + var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; + var {1: b3} = { 1: "string" }; + var {b4 = 1}: any = { b4: 100000 }; + var {b5: { b52 } } = { b5: { b52 } }; + + // V is an object assignment pattern and, for each assignment property P in V, + // P specifies a numeric property name and S has a numeric index signature + // of a type that is assignable to the target given in P, or + + interface F { + [idx: number]: boolean; + } + + function foo(): F { + return { + 1: true + }; + } + + function bar(): F { + return { + 2: true + }; + } + var {1: c0} = foo(); + var {1: c1} = bar(); + + // V is an object assignment pattern and, for each assignment property P in V, + // S has a string index signature of a type that is assignable to the target given in P + + interface F1 { + [str: string]: number; + } + + function foo1(): F1 { + return { + "prop1": 2 + } + } + + var {"prop1": d1} = foo1(); + var {"prop2": d1} = foo1(); \ No newline at end of file diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types index b91838a7a77ee..8ff0f65bcb04b 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.types @@ -87,6 +87,7 @@ var {b5: { b52 } } = { b5: { b52 } }; >{ b52 } : { b52: any; } > : ^^^^^^^^^^^^^ >b52 : any +> : ^^^ // V is an object assignment pattern and, for each assignment property P in V, // P specifies a numeric property name and S has a numeric index signature diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.errors.txt b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.errors.txt new file mode 100644 index 0000000000000..70c82567dcf29 --- /dev/null +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.errors.txt @@ -0,0 +1,60 @@ +destructuringObjectBindingPatternAndAssignment1ES6.ts(6,19): error TS18050: The value 'undefined' cannot be used here. + + +==== destructuringObjectBindingPatternAndAssignment1ES6.ts (1 errors) ==== + // In a destructuring assignment expression, the type of the expression on the right must be assignable to the assignment target on the left. + // An expression of type S is considered assignable to an assignment target V if one of the following is true + + // V is an object assignment pattern and, for each assignment property P in V, + // S is the type Any, or + var { a1 }: any = undefined; + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. + var { a2 }: any = {}; + + // V is an object assignment pattern and, for each assignment property P in V, + // S has an apparent property with the property name specified in + // P of a type that is assignable to the target given in P, or + var { b1, } = { b1:1, }; + var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; + var {1: b3} = { 1: "string" }; + var {b4 = 1}: any = { b4: 100000 }; + var {b5: { b52 } } = { b5: { b52 } }; + + // V is an object assignment pattern and, for each assignment property P in V, + // P specifies a numeric property name and S has a numeric index signature + // of a type that is assignable to the target given in P, or + + interface F { + [idx: number]: boolean; + } + + function foo(): F { + return { + 1: true + }; + } + + function bar(): F { + return { + 2: true + }; + } + var {1: c0} = foo(); + var {1: c1} = bar(); + + // V is an object assignment pattern and, for each assignment property P in V, + // S has a string index signature of a type that is assignable to the target given in P + + interface F1 { + [str: string]: number; + } + + function foo1(): F1 { + return { + "prop1": 2 + } + } + + var {"prop1": d1} = foo1(); + var {"prop2": d1} = foo1(); \ No newline at end of file diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types index 3bfae7da8a707..8aa0bfbb7eb55 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.types @@ -87,6 +87,7 @@ var {b5: { b52 } } = { b5: { b52 } }; >{ b52 } : { b52: any; } > : ^^^^^^^^^^^^^ >b52 : any +> : ^^^ // V is an object assignment pattern and, for each assignment property P in V, // P specifies a numeric property name and S has a numeric index signature diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt index 165d25f1338ec..bc25e6f7ebead 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment3.errors.txt @@ -3,12 +3,13 @@ destructuringObjectBindingPatternAndAssignment3.ts(3,5): error TS2322: Type '{ i destructuringObjectBindingPatternAndAssignment3.ts(3,6): error TS2339: Property 'i' does not exist on type 'string | number'. destructuringObjectBindingPatternAndAssignment3.ts(4,6): error TS2339: Property 'i1' does not exist on type 'string | number | {}'. destructuringObjectBindingPatternAndAssignment3.ts(5,21): error TS2353: Object literal may only specify known properties, and 'f212' does not exist in type '{ f21: any; }'. +destructuringObjectBindingPatternAndAssignment3.ts(5,47): error TS18050: The value 'undefined' cannot be used here. destructuringObjectBindingPatternAndAssignment3.ts(6,7): error TS1005: ':' expected. destructuringObjectBindingPatternAndAssignment3.ts(6,15): error TS1005: ':' expected. destructuringObjectBindingPatternAndAssignment3.ts(7,12): error TS1005: ':' expected. -==== destructuringObjectBindingPatternAndAssignment3.ts (8 errors) ==== +==== destructuringObjectBindingPatternAndAssignment3.ts (9 errors) ==== // Error var {h?} = { h?: 1 }; ~ @@ -24,6 +25,8 @@ destructuringObjectBindingPatternAndAssignment3.ts(7,12): error TS1005: ':' expe var { f2: {f21} = { f212: "string" } }: any = undefined; ~~~~ !!! error TS2353: Object literal may only specify known properties, and 'f212' does not exist in type '{ f21: any; }'. + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. var {1} = { 1 }; ~ !!! error TS1005: ':' expected. diff --git a/tests/baselines/reference/restElementWithNullInitializer.errors.txt b/tests/baselines/reference/restElementWithNullInitializer.errors.txt index f20ec49bf9d58..19a6ec47d21eb 100644 --- a/tests/baselines/reference/restElementWithNullInitializer.errors.txt +++ b/tests/baselines/reference/restElementWithNullInitializer.errors.txt @@ -1,17 +1,23 @@ restElementWithNullInitializer.ts(1,15): error TS2461: Type 'null' is not an array type. +restElementWithNullInitializer.ts(1,24): error TS18050: The value 'null' cannot be used here. restElementWithNullInitializer.ts(4,15): error TS2461: Type 'undefined' is not an array type. +restElementWithNullInitializer.ts(4,24): error TS18050: The value 'undefined' cannot be used here. restElementWithNullInitializer.ts(7,15): error TS2461: Type '{}' is not an array type. -==== restElementWithNullInitializer.ts (3 errors) ==== +==== restElementWithNullInitializer.ts (5 errors) ==== function foo1([...r] = null) { ~~~~~~ !!! error TS2461: Type 'null' is not an array type. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. } function foo2([...r] = undefined) { ~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. + ~~~~~~~~~ +!!! error TS18050: The value 'undefined' cannot be used here. } function foo3([...r] = {}) { diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt index 9f6f76fcffc8a..a5c40ee7c1eff 100644 --- a/tests/baselines/reference/restInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -5,13 +5,15 @@ restInvalidArgumentType.ts(40,13): error TS2700: Rest types may only be created restInvalidArgumentType.ts(42,13): error TS2700: Rest types may only be created from object types. restInvalidArgumentType.ts(43,13): error TS2700: Rest types may only be created from object types. restInvalidArgumentType.ts(45,13): error TS2700: Rest types may only be created from object types. +restInvalidArgumentType.ts(45,20): error TS18048: 'u' is possibly 'undefined'. restInvalidArgumentType.ts(46,13): error TS2700: Rest types may only be created from object types. +restInvalidArgumentType.ts(46,20): error TS18047: 'n' is possibly 'null'. restInvalidArgumentType.ts(50,13): error TS2700: Rest types may only be created from object types. restInvalidArgumentType.ts(51,13): error TS2700: Rest types may only be created from object types. restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created from object types. -==== restInvalidArgumentType.ts (11 errors) ==== +==== restInvalidArgumentType.ts (13 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -71,9 +73,13 @@ restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created var {...r14} = u; // error, undefined-only not allowed ~~~ !!! error TS2700: Rest types may only be created from object types. + ~ +!!! error TS18048: 'u' is possibly 'undefined'. var {...r15} = n; // error, null-only not allowed ~~~ !!! error TS2700: Rest types may only be created from object types. + ~ +!!! error TS18047: 'n' is possibly 'null'. var {...r16} = a; // OK diff --git a/tests/baselines/reference/restUnion2.errors.txt b/tests/baselines/reference/restUnion2.errors.txt new file mode 100644 index 0000000000000..2a075b8089367 --- /dev/null +++ b/tests/baselines/reference/restUnion2.errors.txt @@ -0,0 +1,18 @@ +restUnion2.ts(3,19): error TS18048: 'undefinedUnion' is possibly 'undefined'. +restUnion2.ts(8,19): error TS18047: 'nullUnion' is possibly 'null'. + + +==== restUnion2.ts (2 errors) ==== + declare const undefinedUnion: { n: number } | undefined; + var rest2: { n: number }; + var {...rest2 } = undefinedUnion; + ~~~~~~~~~~~~~~ +!!! error TS18048: 'undefinedUnion' is possibly 'undefined'. + + + declare const nullUnion: { n: number } | null; + var rest3: { n: number }; + var {...rest3 } = nullUnion; + ~~~~~~~~~ +!!! error TS18047: 'nullUnion' is possibly 'null'. + \ No newline at end of file diff --git a/tests/baselines/reference/restUnion3.errors.txt b/tests/baselines/reference/restUnion3.errors.txt index 09de5e683fab8..57c6f989fa2d7 100644 --- a/tests/baselines/reference/restUnion3.errors.txt +++ b/tests/baselines/reference/restUnion3.errors.txt @@ -1,13 +1,16 @@ restUnion3.ts(3,9): error TS2700: Rest types may only be created from object types. +restUnion3.ts(3,19): error TS18049: 'nullAndUndefinedUnion' is possibly 'null' or 'undefined'. restUnion3.ts(7,9): error TS2700: Rest types may only be created from object types. -==== restUnion3.ts (2 errors) ==== +==== restUnion3.ts (3 errors) ==== declare const nullAndUndefinedUnion: null | undefined; var rest4: { }; var {...rest4 } = nullAndUndefinedUnion; ~~~~~ !!! error TS2700: Rest types may only be created from object types. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS18049: 'nullAndUndefinedUnion' is possibly 'null' or 'undefined'. declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; var rest5: { n: number, s: string }; diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index 6e5e472b1c0de..6f123fd0ccf9b 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -22,13 +22,14 @@ unknownType1.ts(143,29): error TS2698: Spread types may only be created from obj unknownType1.ts(144,29): error TS2698: Spread types may only be created from object types. unknownType1.ts(150,17): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. unknownType1.ts(156,14): error TS2700: Rest types may only be created from object types. +unknownType1.ts(156,20): error TS18046: 'x' is of type 'unknown'. unknownType1.ts(162,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. unknownType1.ts(170,9): error TS2322: Type 'T' is not assignable to type '{}'. unknownType1.ts(171,9): error TS2322: Type 'U' is not assignable to type '{}'. unknownType1.ts(181,5): error TS2322: Type 'T' is not assignable to type '{}'. -==== unknownType1.ts (27 errors) ==== +==== unknownType1.ts (28 errors) ==== // In an intersection everything absorbs unknown type T00 = unknown & null; // null @@ -232,6 +233,8 @@ unknownType1.ts(181,5): error TS2322: Type 'T' is not assignable to type '{}'. let { ...a } = x; // Error ~ !!! error TS2700: Rest types may only be created from object types. + ~ +!!! error TS18046: 'x' is of type 'unknown'. } // Class properties of type unknown don't need definite assignment diff --git a/tests/baselines/reference/usingDeclarations.5.errors.txt b/tests/baselines/reference/usingDeclarations.5.errors.txt index ddb56031aa2c8..7e92a1add4460 100644 --- a/tests/baselines/reference/usingDeclarations.5.errors.txt +++ b/tests/baselines/reference/usingDeclarations.5.errors.txt @@ -1,8 +1,9 @@ usingDeclarations.5.ts(3,11): error TS1492: 'using' declarations may not have binding patterns. usingDeclarations.5.ts(3,11): error TS2488: Type 'null' must have a '[Symbol.iterator]()' method that returns an iterator. +usingDeclarations.5.ts(3,17): error TS18050: The value 'null' cannot be used here. -==== usingDeclarations.5.ts (2 errors) ==== +==== usingDeclarations.5.ts (3 errors) ==== { using a = null, [b] = null, @@ -10,6 +11,8 @@ usingDeclarations.5.ts(3,11): error TS2488: Type 'null' must have a '[Symbol.ite !!! error TS1492: 'using' declarations may not have binding patterns. ~~~ !!! error TS2488: Type 'null' must have a '[Symbol.iterator]()' method that returns an iterator. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. c = null; } \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.6.errors.txt b/tests/baselines/reference/usingDeclarations.6.errors.txt index b031165266971..b472cc5ec7846 100644 --- a/tests/baselines/reference/usingDeclarations.6.errors.txt +++ b/tests/baselines/reference/usingDeclarations.6.errors.txt @@ -1,13 +1,16 @@ usingDeclarations.6.ts(2,11): error TS1492: 'using' declarations may not have binding patterns. usingDeclarations.6.ts(2,12): error TS2339: Property 'a' does not exist on type 'null'. +usingDeclarations.6.ts(2,17): error TS18050: The value 'null' cannot be used here. -==== usingDeclarations.6.ts (2 errors) ==== +==== usingDeclarations.6.ts (3 errors) ==== { using {a} = null; ~~~ !!! error TS1492: 'using' declarations may not have binding patterns. ~ !!! error TS2339: Property 'a' does not exist on type 'null'. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. } \ No newline at end of file diff --git a/tests/baselines/reference/usingDeclarations.7.errors.txt b/tests/baselines/reference/usingDeclarations.7.errors.txt index 78bb1f9050195..5802da6db031c 100644 --- a/tests/baselines/reference/usingDeclarations.7.errors.txt +++ b/tests/baselines/reference/usingDeclarations.7.errors.txt @@ -1,8 +1,9 @@ usingDeclarations.7.ts(3,11): error TS1492: 'using' declarations may not have binding patterns. usingDeclarations.7.ts(3,12): error TS2339: Property 'b' does not exist on type 'null'. +usingDeclarations.7.ts(3,17): error TS18050: The value 'null' cannot be used here. -==== usingDeclarations.7.ts (2 errors) ==== +==== usingDeclarations.7.ts (3 errors) ==== { using a = null, {b} = null, @@ -10,5 +11,7 @@ usingDeclarations.7.ts(3,12): error TS2339: Property 'b' does not exist on type !!! error TS1492: 'using' declarations may not have binding patterns. ~ !!! error TS2339: Property 'b' does not exist on type 'null'. + ~~~~ +!!! error TS18050: The value 'null' cannot be used here. c = null; } \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts new file mode 100644 index 0000000000000..0cbdea47c2885 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts @@ -0,0 +1,22 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/60119 + +interface T { + a?: unknown; + b?: unknown; + c?: unknown; +} + +function f1(k: L, t: T | undefined) { + const { [k]: v } = t; +} + +function f2(k: L, t: T | null) { + const { [k]: v } = t; +} + +function f3(k: L, t: T | null | undefined) { + const { [k]: v } = t; +} From 282ee86ddcdb546a08c1225f779d222cba40d2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 3 Oct 2024 08:16:16 +0200 Subject: [PATCH 2/4] fixed issue with nullable parent types in binding patterns --- src/compiler/checker.ts | 9 +++- ...PatternWithNullableInitializer1.errors.txt | 9 +++- ...ingPatternWithNullableInitializer1.symbols | 17 +++++++ ...ndingPatternWithNullableInitializer1.types | 21 +++++++++ ...eunknownincatchvariables=false).errors.txt | 23 +++++++++- ...seunknownincatchvariables=true).errors.txt | 44 ++++++++++++++++++- ...rayBindingPatternAndAssignment2.errors.txt | 8 +++- .../reference/downlevelLetConst16.errors.txt | 14 +++++- ...terBeforeNonoptionalNotOptional.errors.txt | 27 ++++++++++++ .../bindingPatternWithNullableInitializer1.ts | 4 ++ 10 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 296ad1ff46abd..7599bec291389 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44454,8 +44454,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // check private/protected variable access const parent = node.parent.parent; const parentCheckMode = node.dotDotDotToken ? CheckMode.RestBindingElement : CheckMode.Normal; - const parentType = getTypeForBindingElementParent(parent, parentCheckMode); const name = node.propertyName || node.name; + + let parentType = getTypeForBindingElementParent(parent, parentCheckMode); + if (parentType && !parent.initializer) { + parentType = checkNonNullType(parentType, parent); + } + if (parentType && !isBindingPattern(name)) { const exprType = getLiteralTypeFromPropertyName(name); if (isTypeUsableAsPropertyName(exprType)) { @@ -44487,7 +44492,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isInAmbientOrTypeNode(node)) { return; } - const needCheckInitializer = hasOnlyExpressionInitializer(node) && node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement; + const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement; const needCheckWidenedType = !some(node.name.elements, not(isOmittedExpression)); if (needCheckInitializer || needCheckWidenedType) { // Don't validate for-in initializer as it is already an error diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt index a914cb1c3895e..ac1ebece24f07 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt @@ -1,9 +1,10 @@ bindingPatternWithNullableInitializer1.ts(10,22): error TS18048: 't' is possibly 'undefined'. bindingPatternWithNullableInitializer1.ts(14,22): error TS18047: 't' is possibly 'null'. bindingPatternWithNullableInitializer1.ts(18,22): error TS18049: 't' is possibly 'null' or 'undefined'. +bindingPatternWithNullableInitializer1.ts(22,14): error TS2532: Object is possibly 'undefined'. -==== bindingPatternWithNullableInitializer1.ts (3 errors) ==== +==== bindingPatternWithNullableInitializer1.ts (4 errors) ==== // https://github.com/microsoft/TypeScript/issues/60119 interface T { @@ -29,4 +30,10 @@ bindingPatternWithNullableInitializer1.ts(18,22): error TS18049: 't' is possibly ~ !!! error TS18049: 't' is possibly 'null' or 'undefined'. } + + function f4(k: L, t: { f: T | undefined }) { + const { f: { [k]: v } } = t; + ~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } \ No newline at end of file diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols index 3cc6d53ed1757..aef37b5aea6ab 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols @@ -61,3 +61,20 @@ function f3(k: L, t: T | null | undefined) { >t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 16, 36)) } +function f4(k: L, t: { f: T | undefined }) { +>f4 : Symbol(f4, Decl(bindingPatternWithNullableInitializer1.ts, 18, 1)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 20, 12)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 20, 31)) +>L : Symbol(L, Decl(bindingPatternWithNullableInitializer1.ts, 20, 12)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 20, 36)) +>f : Symbol(f, Decl(bindingPatternWithNullableInitializer1.ts, 20, 41)) +>T : Symbol(T, Decl(bindingPatternWithNullableInitializer1.ts, 0, 0)) + + const { f: { [k]: v } } = t; +>f : Symbol(f, Decl(bindingPatternWithNullableInitializer1.ts, 20, 41)) +>k : Symbol(k, Decl(bindingPatternWithNullableInitializer1.ts, 20, 31)) +>v : Symbol(v, Decl(bindingPatternWithNullableInitializer1.ts, 21, 14)) +>t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 20, 36)) +} + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.types b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types index f804ae1730855..c6957b2edf984 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.types +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types @@ -68,3 +68,24 @@ function f3(k: L, t: T | null | undefined) { > : ^^^^^^^^^^^^^^^^^^^^ } +function f4(k: L, t: { f: T | undefined }) { +>f4 : (k: L, t: { f: T | undefined; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ +>k : L +> : ^ +>t : { f: T | undefined; } +> : ^^^^^ ^^^ +>f : T | undefined +> : ^^^^^^^^^^^^^ + + const { f: { [k]: v } } = t; +>f : any +> : ^^^ +>k : L +> : ^ +>v : (T | undefined)[L] +> : ^^^^^^^^^^^^^^^^^^ +>t : { f: T | undefined; } +> : ^^^^^ ^^^ +} + diff --git a/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=false).errors.txt b/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=false).errors.txt index 5bb7262052a47..c38c46bd89b0a 100644 --- a/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=false).errors.txt +++ b/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=false).errors.txt @@ -1,13 +1,20 @@ +destructureCatchClause.ts(26,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(26,17): error TS2339: Property 'x' does not exist on type 'unknown'. destructureCatchClause.ts(27,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(27,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(29,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(29,17): error TS2339: Property 'a' does not exist on type 'unknown'. +destructureCatchClause.ts(30,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(30,17): error TS2339: Property 'a' does not exist on type 'unknown'. destructureCatchClause.ts(32,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(32,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(33,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(33,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(35,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(35,17): error TS2339: Property 'a' does not exist on type 'unknown'. -==== destructureCatchClause.ts (7 errors) ==== +==== destructureCatchClause.ts (14 errors) ==== // These are okay with useUnknownInCatchVariables=false, but not okay with useUnknownInCatchVariables=true. try {} catch ({ x }) { x } try {} catch ([ x ]) { x } @@ -34,27 +41,41 @@ destructureCatchClause.ts(35,17): error TS2339: Property 'a' does not exist on t try {} catch ({ x }: unknown) { x } + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'x' does not exist on type 'unknown'. try {} catch ([ x ]: unknown) { x } ~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { x } }: unknown) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ({ a: [ x ] }: unknown) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ([{ x }]: unknown) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ([[ x ]]: unknown) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { b: { c: { x }} }}: unknown) { x } + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. \ No newline at end of file diff --git a/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=true).errors.txt b/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=true).errors.txt index e01d50c85c9c2..1467ff162ebb6 100644 --- a/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=true).errors.txt +++ b/tests/baselines/reference/destructureCatchClause(strict=true,useunknownincatchvariables=true).errors.txt @@ -1,43 +1,71 @@ +destructureCatchClause.ts(2,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(2,17): error TS2339: Property 'x' does not exist on type 'unknown'. destructureCatchClause.ts(3,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(3,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(5,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(5,17): error TS2339: Property 'a' does not exist on type 'unknown'. +destructureCatchClause.ts(6,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(6,17): error TS2339: Property 'a' does not exist on type 'unknown'. destructureCatchClause.ts(8,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(8,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(9,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(9,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(11,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(11,17): error TS2339: Property 'a' does not exist on type 'unknown'. +destructureCatchClause.ts(26,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(26,17): error TS2339: Property 'x' does not exist on type 'unknown'. destructureCatchClause.ts(27,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(27,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(29,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(29,17): error TS2339: Property 'a' does not exist on type 'unknown'. +destructureCatchClause.ts(30,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(30,17): error TS2339: Property 'a' does not exist on type 'unknown'. destructureCatchClause.ts(32,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(32,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(33,15): error TS2461: Type 'unknown' is not an array type. +destructureCatchClause.ts(33,15): error TS2571: Object is of type 'unknown'. +destructureCatchClause.ts(35,15): error TS2571: Object is of type 'unknown'. destructureCatchClause.ts(35,17): error TS2339: Property 'a' does not exist on type 'unknown'. -==== destructureCatchClause.ts (14 errors) ==== +==== destructureCatchClause.ts (28 errors) ==== // These are okay with useUnknownInCatchVariables=false, but not okay with useUnknownInCatchVariables=true. try {} catch ({ x }) { x } + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'x' does not exist on type 'unknown'. try {} catch ([ x ]) { x } ~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { x } }) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ({ a: [ x ] }) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ([{ x }]) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ([[ x ]]) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { b: { c: { x }} }}) { x } + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. @@ -55,27 +83,41 @@ destructureCatchClause.ts(35,17): error TS2339: Property 'a' does not exist on t try {} catch ({ x }: unknown) { x } + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'x' does not exist on type 'unknown'. try {} catch ([ x ]: unknown) { x } ~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { x } }: unknown) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ({ a: [ x ] }: unknown) { x } + ~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. try {} catch ([{ x }]: unknown) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ([[ x ]]: unknown) { x } ~~~~~~~ !!! error TS2461: Type 'unknown' is not an array type. + ~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. try {} catch ({ a: { b: { c: { x }} }}: unknown) { x } + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2571: Object is of type 'unknown'. ~ !!! error TS2339: Property 'a' does not exist on type 'unknown'. \ No newline at end of file diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index 8a3cf1159ae43..badc3eb6daa34 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -1,7 +1,9 @@ destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2461: Type 'undefined' is not an array type. destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. +destructuringArrayBindingPatternAndAssignment2.ts(3,6): error TS2532: Object is possibly 'undefined'. destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2461: Type 'undefined' is not an array type. destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. +destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2532: Object is possibly 'undefined'. destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. destructuringArrayBindingPatternAndAssignment2.ts(4,22): error TS18050: The value 'undefined' cannot be used here. destructuringArrayBindingPatternAndAssignment2.ts(9,51): error TS2322: Type 'number' is not assignable to type 'boolean'. @@ -12,7 +14,7 @@ destructuringArrayBindingPatternAndAssignment2.ts(23,5): error TS2322: Type 'num destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' is not an array type. -==== destructuringArrayBindingPatternAndAssignment2.ts (10 errors) ==== +==== destructuringArrayBindingPatternAndAssignment2.ts (12 errors) ==== // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is the type Any, or var [[a0], [[a1]]] = [] // Error @@ -20,10 +22,14 @@ destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' !!! error TS2461: Type 'undefined' is not an array type. ~~~~ !!! error TS2493: Tuple type '[]' of length '0' has no element at index '0'. + ~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. ~~~~~~ !!! error TS2493: Tuple type '[]' of length '0' has no element at index '1'. + ~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. var [[a2], [[a3]]] = undefined // Error ~~~~~~~~~~~~~~ !!! error TS2461: Type 'undefined' is not an array type. diff --git a/tests/baselines/reference/downlevelLetConst16.errors.txt b/tests/baselines/reference/downlevelLetConst16.errors.txt index fe8ff968d7946..bf7123a863144 100644 --- a/tests/baselines/reference/downlevelLetConst16.errors.txt +++ b/tests/baselines/reference/downlevelLetConst16.errors.txt @@ -1,12 +1,16 @@ downlevelLetConst16.ts(151,15): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. downlevelLetConst16.ts(164,17): error TS2493: Tuple type '[]' of length '0' has no element at index '0'. downlevelLetConst16.ts(195,14): error TS2461: Type 'undefined' is not an array type. +downlevelLetConst16.ts(195,14): error TS2532: Object is possibly 'undefined'. +downlevelLetConst16.ts(202,14): error TS2532: Object is possibly 'undefined'. downlevelLetConst16.ts(202,15): error TS2339: Property 'a' does not exist on type 'undefined'. downlevelLetConst16.ts(216,16): error TS2461: Type 'undefined' is not an array type. +downlevelLetConst16.ts(216,16): error TS2532: Object is possibly 'undefined'. +downlevelLetConst16.ts(223,16): error TS2532: Object is possibly 'undefined'. downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on type 'undefined'. -==== downlevelLetConst16.ts (6 errors) ==== +==== downlevelLetConst16.ts (10 errors) ==== 'use strict' declare function use(a: any); @@ -208,6 +212,8 @@ downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on typ for (let [x] of []) { ~~~ !!! error TS2461: Type 'undefined' is not an array type. + ~~~ +!!! error TS2532: Object is possibly 'undefined'. use(x); } use(x); @@ -215,6 +221,8 @@ downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on typ function foo9() { for (let {a: x} of []) { + ~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2339: Property 'a' does not exist on type 'undefined'. use(x); @@ -233,6 +241,8 @@ downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on typ for (const [x] of []) { ~~~ !!! error TS2461: Type 'undefined' is not an array type. + ~~~ +!!! error TS2532: Object is possibly 'undefined'. use(x); } use(x); @@ -240,6 +250,8 @@ downlevelLetConst16.ts(223,17): error TS2339: Property 'a' does not exist on typ function foo12() { for (const {a: x} of []) { + ~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. ~ !!! error TS2339: Property 'a' does not exist on type 'undefined'. use(x); diff --git a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.errors.txt b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.errors.txt new file mode 100644 index 0000000000000..50977712fddf5 --- /dev/null +++ b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.errors.txt @@ -0,0 +1,27 @@ +index.d.ts(4,30): error TS2532: Object is possibly 'undefined'. +index.d.ts(7,30): error TS2532: Object is possibly 'undefined'. +index.d.ts(7,37): error TS2532: Object is possibly 'undefined'. + + +==== index.d.ts (3 errors) ==== + export declare function foo({a}?: { + a?: string; + }): void; + export declare function foo2({a}: { + ~~~~~~ + a?: string | undefined; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } | undefined, b: string): void; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + export declare function foo3({a, b: {c}}: { + ~~~~~~~~~~~~~~ + ~~~ +!!! error TS2532: Object is possibly 'undefined'. + a?: string | undefined; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + b?: {c?: string | undefined;} | undefined; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } | undefined, b: string): void; + ~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts index 0cbdea47c2885..1f88cc41152d8 100644 --- a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts +++ b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts @@ -20,3 +20,7 @@ function f2(k: L, t: T | null) { function f3(k: L, t: T | null | undefined) { const { [k]: v } = t; } + +function f4(k: L, t: { f: T | undefined }) { + const { f: { [k]: v } } = t; +} From c0ef60948eb1910d923cb26252d2f4781adcd284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 10 Oct 2024 11:27:02 +0200 Subject: [PATCH 3/4] add extra test case --- ...PatternWithNullableInitializer1.errors.txt | 13 ++++++- ...ingPatternWithNullableInitializer1.symbols | 22 ++++++++++++ ...ndingPatternWithNullableInitializer1.types | 36 +++++++++++++++++++ .../bindingPatternWithNullableInitializer1.ts | 8 +++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt index ac1ebece24f07..e7f198e2fda03 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.errors.txt @@ -2,9 +2,10 @@ bindingPatternWithNullableInitializer1.ts(10,22): error TS18048: 't' is possibly bindingPatternWithNullableInitializer1.ts(14,22): error TS18047: 't' is possibly 'null'. bindingPatternWithNullableInitializer1.ts(18,22): error TS18049: 't' is possibly 'null' or 'undefined'. bindingPatternWithNullableInitializer1.ts(22,14): error TS2532: Object is possibly 'undefined'. +bindingPatternWithNullableInitializer1.ts(31,18): error TS18048: 'input.a.b' is possibly 'undefined'. -==== bindingPatternWithNullableInitializer1.ts (4 errors) ==== +==== bindingPatternWithNullableInitializer1.ts (5 errors) ==== // https://github.com/microsoft/TypeScript/issues/60119 interface T { @@ -36,4 +37,14 @@ bindingPatternWithNullableInitializer1.ts(22,14): error TS2532: Object is possib ~~~~~~~~~~ !!! error TS2532: Object is possibly 'undefined'. } + + // https://github.com/microsoft/TypeScript/issues/60179 + + const input: { + a?: { b?: { c: string } }; + } = { a: undefined }; + + const { ...b } = input.a?.b; + ~~~~~~~~~~ +!!! error TS18048: 'input.a.b' is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols index aef37b5aea6ab..2deb43e0b9608 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.symbols @@ -78,3 +78,25 @@ function f4(k: L, t: { f: T | undefined }) { >t : Symbol(t, Decl(bindingPatternWithNullableInitializer1.ts, 20, 36)) } +// https://github.com/microsoft/TypeScript/issues/60179 + +const input: { +>input : Symbol(input, Decl(bindingPatternWithNullableInitializer1.ts, 26, 5)) + + a?: { b?: { c: string } }; +>a : Symbol(a, Decl(bindingPatternWithNullableInitializer1.ts, 26, 14)) +>b : Symbol(b, Decl(bindingPatternWithNullableInitializer1.ts, 27, 7)) +>c : Symbol(c, Decl(bindingPatternWithNullableInitializer1.ts, 27, 13)) + +} = { a: undefined }; +>a : Symbol(a, Decl(bindingPatternWithNullableInitializer1.ts, 28, 5)) +>undefined : Symbol(undefined) + +const { ...b } = input.a?.b; +>b : Symbol(b, Decl(bindingPatternWithNullableInitializer1.ts, 30, 7)) +>input.a?.b : Symbol(b, Decl(bindingPatternWithNullableInitializer1.ts, 27, 7)) +>input.a : Symbol(a, Decl(bindingPatternWithNullableInitializer1.ts, 26, 14)) +>input : Symbol(input, Decl(bindingPatternWithNullableInitializer1.ts, 26, 5)) +>a : Symbol(a, Decl(bindingPatternWithNullableInitializer1.ts, 26, 14)) +>b : Symbol(b, Decl(bindingPatternWithNullableInitializer1.ts, 27, 7)) + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer1.types b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types index c6957b2edf984..35c1062e5eb45 100644 --- a/tests/baselines/reference/bindingPatternWithNullableInitializer1.types +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer1.types @@ -89,3 +89,39 @@ function f4(k: L, t: { f: T | undefined }) { > : ^^^^^ ^^^ } +// https://github.com/microsoft/TypeScript/issues/60179 + +const input: { +>input : { a?: { b?: { c: string; }; }; } +> : ^^^^^^ ^^^ + + a?: { b?: { c: string } }; +>a : { b?: { c: string; }; } | undefined +> : ^^^^^^ ^^^^^^^^^^^^^^^ +>b : { c: string; } | undefined +> : ^^^^^ ^^^^^^^^^^^^^^^ +>c : string +> : ^^^^^^ + +} = { a: undefined }; +>{ a: undefined } : { a: undefined; } +> : ^^^^^^^^^^^^^^^^^ +>a : undefined +> : ^^^^^^^^^ +>undefined : undefined +> : ^^^^^^^^^ + +const { ...b } = input.a?.b; +>b : { c: string; } +> : ^^^^^ ^^^ +>input.a?.b : { c: string; } | undefined +> : ^^^^^ ^^^^^^^^^^^^^^^ +>input.a : { b?: { c: string; }; } | undefined +> : ^^^^^^ ^^^^^^^^^^^^^^^ +>input : { a?: { b?: { c: string; }; }; } +> : ^^^^^^ ^^^ +>a : { b?: { c: string; }; } | undefined +> : ^^^^^^ ^^^^^^^^^^^^^^^ +>b : { c: string; } | undefined +> : ^^^^^ ^^^^^^^^^^^^^^^ + diff --git a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts index 1f88cc41152d8..e5b8fdb8f43e4 100644 --- a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts +++ b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer1.ts @@ -24,3 +24,11 @@ function f3(k: L, t: T | null | undefined) { function f4(k: L, t: { f: T | undefined }) { const { f: { [k]: v } } = t; } + +// https://github.com/microsoft/TypeScript/issues/60179 + +const input: { + a?: { b?: { c: string } }; +} = { a: undefined }; + +const { ...b } = input.a?.b; From fff34bca16eec25abc5d3cd613d043af06165b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 24 Aug 2025 00:09:53 +0200 Subject: [PATCH 4/4] add extra test --- .../bindingPatternWithNullableInitializer2.js | 54 ++++++++++++ ...ingPatternWithNullableInitializer2.symbols | 65 ++++++++++++++ ...ndingPatternWithNullableInitializer2.types | 87 +++++++++++++++++++ ...ingPatternWithNullableInitializer3.symbols | 30 +++++++ ...ndingPatternWithNullableInitializer3.types | 35 ++++++++ .../bindingPatternWithNullableInitializer2.ts | 35 ++++++++ .../bindingPatternWithNullableInitializer3.ts | 16 ++++ 7 files changed, 322 insertions(+) create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer2.js create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer2.symbols create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer2.types create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer3.symbols create mode 100644 tests/baselines/reference/bindingPatternWithNullableInitializer3.types create mode 100644 tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts create mode 100644 tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer2.js b/tests/baselines/reference/bindingPatternWithNullableInitializer2.js new file mode 100644 index 0000000000000..a796291a56f1b --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer2.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts] //// + +//// [bindingPatternWithNullableInitializer2.ts] +export async function focus( + { + emitSynthFocused, + }: { + emitSynthFocused: boolean; + } = { emitSynthFocused: true }, +) {} + +export declare function focus2({ + emitSynthFocused, +}?: { + emitSynthFocused: boolean; +}): Promise; + +export class View { + async focus( + { + emitSynthFocused, + }: { + emitSynthFocused: boolean; + } = { emitSynthFocused: true }, + ) {} +} + +// emit of the above +export declare class View2 { + focus({ emitSynthFocused }?: { + emitSynthFocused: boolean; + }): Promise; +} + + + + +//// [bindingPatternWithNullableInitializer2.d.ts] +export declare function focus({ emitSynthFocused, }?: { + emitSynthFocused: boolean; +}): Promise; +export declare function focus2({ emitSynthFocused, }?: { + emitSynthFocused: boolean; +}): Promise; +export declare class View { + focus({ emitSynthFocused, }?: { + emitSynthFocused: boolean; + }): Promise; +} +export declare class View2 { + focus({ emitSynthFocused }?: { + emitSynthFocused: boolean; + }): Promise; +} diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer2.symbols b/tests/baselines/reference/bindingPatternWithNullableInitializer2.symbols new file mode 100644 index 0000000000000..3ecadb6d1bff2 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer2.symbols @@ -0,0 +1,65 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts] //// + +=== bindingPatternWithNullableInitializer2.ts === +export async function focus( +>focus : Symbol(focus, Decl(bindingPatternWithNullableInitializer2.ts, 0, 0)) + { + emitSynthFocused, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 1, 3)) + + }: { + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 3, 6)) + + } = { emitSynthFocused: true }, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 5, 7)) + +) {} + +export declare function focus2({ +>focus2 : Symbol(focus2, Decl(bindingPatternWithNullableInitializer2.ts, 6, 4)) + + emitSynthFocused, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 8, 32)) + +}?: { + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 10, 5)) + +}): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) + +export class View { +>View : Symbol(View, Decl(bindingPatternWithNullableInitializer2.ts, 12, 18)) + + async focus( +>focus : Symbol(View.focus, Decl(bindingPatternWithNullableInitializer2.ts, 14, 19)) + { + emitSynthFocused, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 16, 5)) + + }: { + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 18, 8)) + + } = { emitSynthFocused: true }, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 20, 9)) + + ) {} +} + +// emit of the above +export declare class View2 { +>View2 : Symbol(View2, Decl(bindingPatternWithNullableInitializer2.ts, 22, 1)) + + focus({ emitSynthFocused }?: { +>focus : Symbol(View2.focus, Decl(bindingPatternWithNullableInitializer2.ts, 25, 28)) +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 26, 9)) + + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(bindingPatternWithNullableInitializer2.ts, 26, 32)) + + }): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer2.types b/tests/baselines/reference/bindingPatternWithNullableInitializer2.types new file mode 100644 index 0000000000000..bb3acfae89f86 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer2.types @@ -0,0 +1,87 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts] //// + +=== bindingPatternWithNullableInitializer2.ts === +export async function focus( +>focus : ({ emitSynthFocused, }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^^^^^^^^^^^^^^ + { + emitSynthFocused, +>emitSynthFocused : boolean +> : ^^^^^^^ + + }: { + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + + } = { emitSynthFocused: true }, +>{ emitSynthFocused: true } : { emitSynthFocused: true; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>emitSynthFocused : true +> : ^^^^ +>true : true +> : ^^^^ + +) {} + +export declare function focus2({ +>focus2 : ({ emitSynthFocused, }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^ + + emitSynthFocused, +>emitSynthFocused : boolean +> : ^^^^^^^ + +}?: { + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + +}): Promise; + +export class View { +>View : View +> : ^^^^ + + async focus( +>focus : ({ emitSynthFocused, }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^^^^^^^^^^^^^^ + { + emitSynthFocused, +>emitSynthFocused : boolean +> : ^^^^^^^ + + }: { + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + + } = { emitSynthFocused: true }, +>{ emitSynthFocused: true } : { emitSynthFocused: true; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>emitSynthFocused : true +> : ^^^^ +>true : true +> : ^^^^ + + ) {} +} + +// emit of the above +export declare class View2 { +>View2 : View2 +> : ^^^^^ + + focus({ emitSynthFocused }?: { +>focus : ({ emitSynthFocused }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^ +>emitSynthFocused : boolean +> : ^^^^^^^ + + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + + }): Promise; +} + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer3.symbols b/tests/baselines/reference/bindingPatternWithNullableInitializer3.symbols new file mode 100644 index 0000000000000..b7222b5d14685 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer3.symbols @@ -0,0 +1,30 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts] //// + +=== types.d.ts === +export declare function focus2({ +>focus2 : Symbol(focus2, Decl(types.d.ts, 0, 0)) + + emitSynthFocused, +>emitSynthFocused : Symbol(emitSynthFocused, Decl(types.d.ts, 0, 32)) + +}?: { + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(types.d.ts, 2, 5)) + +}): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) + +export declare class View2 { +>View2 : Symbol(View2, Decl(types.d.ts, 4, 18)) + + focus({ emitSynthFocused }?: { +>focus : Symbol(View2.focus, Decl(types.d.ts, 6, 28)) +>emitSynthFocused : Symbol(emitSynthFocused, Decl(types.d.ts, 7, 9)) + + emitSynthFocused: boolean; +>emitSynthFocused : Symbol(emitSynthFocused, Decl(types.d.ts, 7, 32)) + + }): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/bindingPatternWithNullableInitializer3.types b/tests/baselines/reference/bindingPatternWithNullableInitializer3.types new file mode 100644 index 0000000000000..8c0bee7cb09e8 --- /dev/null +++ b/tests/baselines/reference/bindingPatternWithNullableInitializer3.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts] //// + +=== types.d.ts === +export declare function focus2({ +>focus2 : ({ emitSynthFocused, }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^ + + emitSynthFocused, +>emitSynthFocused : boolean +> : ^^^^^^^ + +}?: { + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + +}): Promise; + +export declare class View2 { +>View2 : View2 +> : ^^^^^ + + focus({ emitSynthFocused }?: { +>focus : ({ emitSynthFocused }?: { emitSynthFocused: boolean; }) => Promise +> : ^ ^^^ ^^^^^ +>emitSynthFocused : boolean +> : ^^^^^^^ + + emitSynthFocused: boolean; +>emitSynthFocused : boolean +> : ^^^^^^^ + + }): Promise; +} + diff --git a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts new file mode 100644 index 0000000000000..b0d6a0acf0635 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer2.ts @@ -0,0 +1,35 @@ +// @strict: true +// @target: esnext +// @declaration: true +// @emitDeclarationOnly: true + +export async function focus( + { + emitSynthFocused, + }: { + emitSynthFocused: boolean; + } = { emitSynthFocused: true }, +) {} + +export declare function focus2({ + emitSynthFocused, +}?: { + emitSynthFocused: boolean; +}): Promise; + +export class View { + async focus( + { + emitSynthFocused, + }: { + emitSynthFocused: boolean; + } = { emitSynthFocused: true }, + ) {} +} + +// emit of the above +export declare class View2 { + focus({ emitSynthFocused }?: { + emitSynthFocused: boolean; + }): Promise; +} diff --git a/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts new file mode 100644 index 0000000000000..77ab9fbf8ee31 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/bindingPatternWithNullableInitializer3.ts @@ -0,0 +1,16 @@ +// @strict: true +// @target: esnext + +// @filename: types.d.ts + +export declare function focus2({ + emitSynthFocused, +}?: { + emitSynthFocused: boolean; +}): Promise; + +export declare class View2 { + focus({ emitSynthFocused }?: { + emitSynthFocused: boolean; + }): Promise; +}