From 4222e9494c5fdff59afba926bdd9f843769563e5 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 21 May 2024 14:58:14 -0700 Subject: [PATCH 1/3] Propagate the error any type in union and intersection construction --- src/compiler/checker.ts | 7 +++++-- src/compiler/types.ts | 4 ++++ .../transpile/declarationSelfReferentialConstraint.d.ts | 8 ++++++++ .../transpile/declarationSelfReferentialConstraint.ts | 5 +++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/transpile/declarationSelfReferentialConstraint.d.ts create mode 100644 tests/cases/transpile/declarationSelfReferentialConstraint.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2a914ab0ec325..1aa00c979edcc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17052,6 +17052,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (flags & TypeFlags.Instantiable) includes |= TypeFlags.IncludesInstantiable; if (flags & TypeFlags.Intersection && getObjectFlags(type) & ObjectFlags.IsConstrainedTypeVariable) includes |= TypeFlags.IncludesConstrainedTypeVariable; if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; + if (isErrorType(type)) includes |= TypeFlags.IncludesError; if (!strictNullChecks && flags & TypeFlags.Nullable) { if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType; } @@ -17303,7 +17304,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (unionReduction !== UnionReduction.None) { if (includes & TypeFlags.AnyOrUnknown) { return includes & TypeFlags.Any ? - includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : + includes & TypeFlags.IncludesWildcard ? wildcardType : + includes & TypeFlags.IncludesError ? errorType : anyType : unknownType; } if (includes & TypeFlags.Undefined) { @@ -17445,6 +17447,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; + if (isErrorType(type)) includes |= TypeFlags.IncludesError; } else if (strictNullChecks || !(flags & TypeFlags.Nullable)) { if (type === missingType) { @@ -17637,7 +17640,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return neverType; } if (includes & TypeFlags.Any) { - return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType; + return includes & TypeFlags.IncludesWildcard ? wildcardType : includes & TypeFlags.IncludesError ? errorType : anyType; } if (!strictNullChecks && includes & TypeFlags.Nullable) { return includes & TypeFlags.IncludesEmptyObject ? neverType : includes & TypeFlags.Undefined ? undefinedType : nullType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 97cd0a4cd889a..df7b59ca7e91f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6185,6 +6185,8 @@ export const enum TypeFlags { StringMapping = 1 << 28, // Uppercase/Lowercase type /** @internal */ Reserved1 = 1 << 29, // Used by union/intersection type construction + /** @internal */ + Reserved2 = 1 << 30, // Used by union/intersection type construction /** @internal */ AnyOrUnknown = Any | Unknown, @@ -6247,6 +6249,8 @@ export const enum TypeFlags { /** @internal */ IncludesConstrainedTypeVariable = Reserved1, /** @internal */ + IncludesError = Reserved2, + /** @internal */ NotPrimitiveUnion = Any | Unknown | Void | Never | Object | Intersection | IncludesInstantiable, } diff --git a/tests/baselines/reference/transpile/declarationSelfReferentialConstraint.d.ts b/tests/baselines/reference/transpile/declarationSelfReferentialConstraint.d.ts new file mode 100644 index 0000000000000..7ac9bb45e671b --- /dev/null +++ b/tests/baselines/reference/transpile/declarationSelfReferentialConstraint.d.ts @@ -0,0 +1,8 @@ +//// [declarationSelfReferentialConstraint.ts] //// +export const object = { + foo: | []>(): void => { }, +}; +//// [declarationSelfReferentialConstraint.d.ts] //// +export declare const object: { + foo: | []>() => void; +}; diff --git a/tests/cases/transpile/declarationSelfReferentialConstraint.ts b/tests/cases/transpile/declarationSelfReferentialConstraint.ts new file mode 100644 index 0000000000000..d9b675e91e527 --- /dev/null +++ b/tests/cases/transpile/declarationSelfReferentialConstraint.ts @@ -0,0 +1,5 @@ +// @declaration: true +// @emitDeclarationOnly: true +export const object = { + foo: | []>(): void => { }, +}; \ No newline at end of file From 15ca54c76b7ba6a5869967ca67462673ae4131a4 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 21 May 2024 15:05:47 -0700 Subject: [PATCH 2/3] Format --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1aa00c979edcc..72ea66311b02a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17305,7 +17305,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (includes & TypeFlags.AnyOrUnknown) { return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : - includes & TypeFlags.IncludesError ? errorType : anyType : + includes & TypeFlags.IncludesError ? errorType : anyType : unknownType; } if (includes & TypeFlags.Undefined) { From ac9b208b766e284b54fab5fbbf36ab3b1b0896c1 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 21 May 2024 22:23:10 +0000 Subject: [PATCH 3/3] Update Baselines and/or Applied Lint Fixes --- ...jsDeclarationsExportDoubleAssignmentInClosure.types | 2 +- .../jsxNestedWithinTernaryParsesCorrectly.types | 2 +- .../reference/logicalAssignment10(target=es2015).types | 4 ++-- .../reference/logicalAssignment10(target=es2020).types | 4 ++-- .../reference/logicalAssignment10(target=es2021).types | 4 ++-- .../reference/logicalAssignment10(target=esnext).types | 4 ++-- .../parsingDeepParenthensizedExpression.types | 8 ++++---- tests/baselines/reference/tsxReactEmitNesting.types | 2 +- .../unionOfFunctionAndSignatureIsCallable.types | 10 +++++----- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.types b/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.types index ba280e2272d1d..967819f0e1541 100644 --- a/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.types +++ b/tests/baselines/reference/jsDeclarationsExportDoubleAssignmentInClosure.types @@ -23,7 +23,7 @@ function foo() { >o : any return (o == null) ? create(base) : defineProperties(Object(o), descriptors); ->(o == null) ? create(base) : defineProperties(Object(o), descriptors) : any +>(o == null) ? create(base) : defineProperties(Object(o), descriptors) : error >(o == null) : boolean > : ^^^^^^^ >o == null : boolean diff --git a/tests/baselines/reference/jsxNestedWithinTernaryParsesCorrectly.types b/tests/baselines/reference/jsxNestedWithinTernaryParsesCorrectly.types index 3692125c170d7..4e13f6e17bdb1 100644 --- a/tests/baselines/reference/jsxNestedWithinTernaryParsesCorrectly.types +++ b/tests/baselines/reference/jsxNestedWithinTernaryParsesCorrectly.types @@ -15,7 +15,7 @@ const a = ( > : ^^^ {0 ? ( ->0 ? ( emptyMessage // must be identifier? ) : ( // must be exactly two expression holes {0}{0} ) : any +>0 ? ( emptyMessage // must be identifier? ) : ( // must be exactly two expression holes {0}{0} ) : error >0 : 0 > : ^ >( emptyMessage // must be identifier? ) : any diff --git a/tests/baselines/reference/logicalAssignment10(target=es2015).types b/tests/baselines/reference/logicalAssignment10(target=es2015).types index c84289132b4a0..3044fc2efa37f 100644 --- a/tests/baselines/reference/logicalAssignment10(target=es2015).types +++ b/tests/baselines/reference/logicalAssignment10(target=es2015).types @@ -36,7 +36,7 @@ const oobj = { } obj[incr()] ??= incr(); ->obj[incr()] ??= incr() : any +>obj[incr()] ??= incr() : error >obj[incr()] : error >obj : {} > : ^^ @@ -50,7 +50,7 @@ obj[incr()] ??= incr(); > : ^^^^^^^^^^^^ oobj["obj"][incr()] ??= incr(); ->oobj["obj"][incr()] ??= incr() : any +>oobj["obj"][incr()] ??= incr() : error >oobj["obj"][incr()] : error >oobj["obj"] : {} > : ^^ diff --git a/tests/baselines/reference/logicalAssignment10(target=es2020).types b/tests/baselines/reference/logicalAssignment10(target=es2020).types index c84289132b4a0..3044fc2efa37f 100644 --- a/tests/baselines/reference/logicalAssignment10(target=es2020).types +++ b/tests/baselines/reference/logicalAssignment10(target=es2020).types @@ -36,7 +36,7 @@ const oobj = { } obj[incr()] ??= incr(); ->obj[incr()] ??= incr() : any +>obj[incr()] ??= incr() : error >obj[incr()] : error >obj : {} > : ^^ @@ -50,7 +50,7 @@ obj[incr()] ??= incr(); > : ^^^^^^^^^^^^ oobj["obj"][incr()] ??= incr(); ->oobj["obj"][incr()] ??= incr() : any +>oobj["obj"][incr()] ??= incr() : error >oobj["obj"][incr()] : error >oobj["obj"] : {} > : ^^ diff --git a/tests/baselines/reference/logicalAssignment10(target=es2021).types b/tests/baselines/reference/logicalAssignment10(target=es2021).types index c84289132b4a0..3044fc2efa37f 100644 --- a/tests/baselines/reference/logicalAssignment10(target=es2021).types +++ b/tests/baselines/reference/logicalAssignment10(target=es2021).types @@ -36,7 +36,7 @@ const oobj = { } obj[incr()] ??= incr(); ->obj[incr()] ??= incr() : any +>obj[incr()] ??= incr() : error >obj[incr()] : error >obj : {} > : ^^ @@ -50,7 +50,7 @@ obj[incr()] ??= incr(); > : ^^^^^^^^^^^^ oobj["obj"][incr()] ??= incr(); ->oobj["obj"][incr()] ??= incr() : any +>oobj["obj"][incr()] ??= incr() : error >oobj["obj"][incr()] : error >oobj["obj"] : {} > : ^^ diff --git a/tests/baselines/reference/logicalAssignment10(target=esnext).types b/tests/baselines/reference/logicalAssignment10(target=esnext).types index c84289132b4a0..3044fc2efa37f 100644 --- a/tests/baselines/reference/logicalAssignment10(target=esnext).types +++ b/tests/baselines/reference/logicalAssignment10(target=esnext).types @@ -36,7 +36,7 @@ const oobj = { } obj[incr()] ??= incr(); ->obj[incr()] ??= incr() : any +>obj[incr()] ??= incr() : error >obj[incr()] : error >obj : {} > : ^^ @@ -50,7 +50,7 @@ obj[incr()] ??= incr(); > : ^^^^^^^^^^^^ oobj["obj"][incr()] ??= incr(); ->oobj["obj"][incr()] ??= incr() : any +>oobj["obj"][incr()] ??= incr() : error >oobj["obj"][incr()] : error >oobj["obj"] : {} > : ^^ diff --git a/tests/baselines/reference/parsingDeepParenthensizedExpression.types b/tests/baselines/reference/parsingDeepParenthensizedExpression.types index d88fde50c7be8..5f9591f718091 100644 --- a/tests/baselines/reference/parsingDeepParenthensizedExpression.types +++ b/tests/baselines/reference/parsingDeepParenthensizedExpression.types @@ -101,11 +101,11 @@ function Y(e, t) { > : ^^^^^^ >v = f, (0 | (f = f + 288 | 0)) >= (0 | l) && b(288), T = v, A = t : any >v = f, (0 | (f = f + 288 | 0)) >= (0 | l) && b(288), T = v : error ->v = f, (0 | (f = f + 288 | 0)) >= (0 | l) && b(288) : any +>v = f, (0 | (f = f + 288 | 0)) >= (0 | l) && b(288) : error >v = f : error >v : any >f : error ->(0 | (f = f + 288 | 0)) >= (0 | l) && b(288) : any +>(0 | (f = f + 288 | 0)) >= (0 | l) && b(288) : error >(0 | (f = f + 288 | 0)) >= (0 | l) : boolean > : ^^^^^^^ >(0 | (f = f + 288 | 0)) : number @@ -298,11 +298,11 @@ function Y(e, t) { > : ^^^^^^ >s = f, (0 | (f = f + 32 | 0)) >= (0 | l) && b(32), i = e, a = t : any >s = f, (0 | (f = f + 32 | 0)) >= (0 | l) && b(32), i = e : error ->s = f, (0 | (f = f + 32 | 0)) >= (0 | l) && b(32) : any +>s = f, (0 | (f = f + 32 | 0)) >= (0 | l) && b(32) : error >s = f : error >s : any >f : error ->(0 | (f = f + 32 | 0)) >= (0 | l) && b(32) : any +>(0 | (f = f + 32 | 0)) >= (0 | l) && b(32) : error >(0 | (f = f + 32 | 0)) >= (0 | l) : boolean > : ^^^^^^^ >(0 | (f = f + 32 | 0)) : number diff --git a/tests/baselines/reference/tsxReactEmitNesting.types b/tests/baselines/reference/tsxReactEmitNesting.types index e30a0f8ab16b1..3aca18ca9f9ef 100644 --- a/tests/baselines/reference/tsxReactEmitNesting.types +++ b/tests/baselines/reference/tsxReactEmitNesting.types @@ -191,7 +191,7 @@ let render = (ctrl, model) => > : ^^^^^^ {(!todo.editable) ? ->(!todo.editable) ? : null : any +>(!todo.editable) ? : null : error >(!todo.editable) : boolean > : ^^^^^^^ >!todo.editable : boolean diff --git a/tests/baselines/reference/unionOfFunctionAndSignatureIsCallable.types b/tests/baselines/reference/unionOfFunctionAndSignatureIsCallable.types index 614ae011e3953..dce4023dea18e 100644 --- a/tests/baselines/reference/unionOfFunctionAndSignatureIsCallable.types +++ b/tests/baselines/reference/unionOfFunctionAndSignatureIsCallable.types @@ -30,8 +30,8 @@ function f1(c1: Function, c2: () => object, callable: typeof c1 | typeof c2) { > : ^^^^^^^^^^^^ const c = callable(); ->c : any ->callable() : any +>c : error +>callable() : error >callable : Function | (() => object) > : ^^^^^^^^^^^^^^^^^^^^^^^^^ } @@ -43,8 +43,8 @@ function f2(fetcherParams: object | (() => object)) { > : ^^^^^^^^^^^^^^^^ ^ const data = typeof fetcherParams === 'function' ->data : any ->typeof fetcherParams === 'function' ? fetcherParams() : fetcherParams : any +>data : error +>typeof fetcherParams === 'function' ? fetcherParams() : fetcherParams : error >typeof fetcherParams === 'function' : boolean > : ^^^^^^^ >typeof fetcherParams : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -55,7 +55,7 @@ function f2(fetcherParams: object | (() => object)) { > : ^^^^^^^^^^ ? fetcherParams() ->fetcherParams() : any +>fetcherParams() : error >fetcherParams : Function | (() => object) > : ^^^^^^^^^^^^^^^^^^^^^^^^^