From 7f11456f4afd816776c08208389e10d8c5a62dd8 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 13 Mar 2024 08:48:21 -0700 Subject: [PATCH 01/10] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#57751=20(Excl?= =?UTF-8?q?ude=20generic=20string-like=20types=20f...)=20into=20release-5.?= =?UTF-8?q?4=20(#57753)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anders Hejlsberg --- src/compiler/checker.ts | 11 ++- ...tionReductionGenericStringLikeType.symbols | 77 +++++++++++++++++++ ...ectionReductionGenericStringLikeType.types | 44 +++++++++++ ...ersectionReductionGenericStringLikeType.ts | 31 ++++++++ 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/intersectionReductionGenericStringLikeType.symbols create mode 100644 tests/baselines/reference/intersectionReductionGenericStringLikeType.types create mode 100644 tests/cases/compiler/intersectionReductionGenericStringLikeType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f9ab74b053256..583c4827e63c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17624,7 +17624,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeVarIndex = typeSet[0].flags & TypeFlags.TypeVariable ? 0 : 1; const typeVariable = typeSet[typeVarIndex]; const primitiveType = typeSet[1 - typeVarIndex]; - if (typeVariable.flags & TypeFlags.TypeVariable && (primitiveType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive) || includes & TypeFlags.IncludesEmptyObject)) { + if ( + typeVariable.flags & TypeFlags.TypeVariable && + (primitiveType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive) && !isGenericStringLikeType(primitiveType) || includes & TypeFlags.IncludesEmptyObject) + ) { // We have an intersection T & P or P & T, where T is a type variable and P is a primitive type, the object type, or {}. const constraint = getBaseConstraintOfType(typeVariable); // Check that T's constraint is similarly composed of primitive types, the object type, or {}. @@ -18374,6 +18377,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { !!(type.flags & TypeFlags.StringMapping) && isPatternLiteralPlaceholderType((type as StringMappingType).type); } + function isGenericStringLikeType(type: Type) { + return !!(type.flags & (TypeFlags.TemplateLiteral | TypeFlags.StringMapping)) && !isPatternLiteralType(type); + } + function isGenericType(type: Type): boolean { return !!getGenericObjectFlags(type); } @@ -18402,7 +18409,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return (type as SubstitutionType).objectFlags & ObjectFlags.IsGenericType; } return (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type) || isGenericTupleType(type) ? ObjectFlags.IsGenericObjectType : 0) | - (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0); + (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index) || isGenericStringLikeType(type) ? ObjectFlags.IsGenericIndexType : 0); } function getSimplifiedType(type: Type, writing: boolean): Type { diff --git a/tests/baselines/reference/intersectionReductionGenericStringLikeType.symbols b/tests/baselines/reference/intersectionReductionGenericStringLikeType.symbols new file mode 100644 index 0000000000000..ad256535dde14 --- /dev/null +++ b/tests/baselines/reference/intersectionReductionGenericStringLikeType.symbols @@ -0,0 +1,77 @@ +//// [tests/cases/compiler/intersectionReductionGenericStringLikeType.ts] //// + +=== intersectionReductionGenericStringLikeType.ts === +// https://github.com/microsoft/TypeScript/issues/57736 + +type obj = { +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) + + foo: 1; +>foo : Symbol(foo, Decl(intersectionReductionGenericStringLikeType.ts, 2, 12)) + + bar: 2; +>bar : Symbol(bar, Decl(intersectionReductionGenericStringLikeType.ts, 3, 11)) + +}; + +type keyContaining1< +>keyContaining1 : Symbol(keyContaining1, Decl(intersectionReductionGenericStringLikeType.ts, 5, 2)) + + str extends string, +>str : Symbol(str, Decl(intersectionReductionGenericStringLikeType.ts, 7, 20)) + + keys extends keyof obj = keyof obj, +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 8, 23)) +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) + +> = keys extends infer key extends keyof obj +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 8, 23)) +>key : Symbol(key, Decl(intersectionReductionGenericStringLikeType.ts, 10, 22)) +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) + + ? key extends `${string}${str}${string}` +>key : Symbol(key, Decl(intersectionReductionGenericStringLikeType.ts, 10, 22)) +>str : Symbol(str, Decl(intersectionReductionGenericStringLikeType.ts, 7, 20)) + + ? obj[key] +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) +>key : Symbol(key, Decl(intersectionReductionGenericStringLikeType.ts, 10, 22)) + + : never + : never; + +type _1 = keyContaining1<"foo">; // 1 +>_1 : Symbol(_1, Decl(intersectionReductionGenericStringLikeType.ts, 14, 12)) +>keyContaining1 : Symbol(keyContaining1, Decl(intersectionReductionGenericStringLikeType.ts, 5, 2)) + +type keyContaining2< +>keyContaining2 : Symbol(keyContaining2, Decl(intersectionReductionGenericStringLikeType.ts, 16, 32)) + + str extends string, +>str : Symbol(str, Decl(intersectionReductionGenericStringLikeType.ts, 18, 20)) + + keys extends keyof obj = keyof obj, +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 19, 23)) +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) + +> = keys extends keys +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 19, 23)) +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 19, 23)) + + ? keys extends `${string}${str}${string}` +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 19, 23)) +>str : Symbol(str, Decl(intersectionReductionGenericStringLikeType.ts, 18, 20)) + + ? obj[keys] +>obj : Symbol(obj, Decl(intersectionReductionGenericStringLikeType.ts, 0, 0)) +>keys : Symbol(keys, Decl(intersectionReductionGenericStringLikeType.ts, 19, 23)) + + : never + : never; + +type _2 = keyContaining2<"foo">; // 1 +>_2 : Symbol(_2, Decl(intersectionReductionGenericStringLikeType.ts, 25, 12)) +>keyContaining2 : Symbol(keyContaining2, Decl(intersectionReductionGenericStringLikeType.ts, 16, 32)) + diff --git a/tests/baselines/reference/intersectionReductionGenericStringLikeType.types b/tests/baselines/reference/intersectionReductionGenericStringLikeType.types new file mode 100644 index 0000000000000..0d3af56acf2ad --- /dev/null +++ b/tests/baselines/reference/intersectionReductionGenericStringLikeType.types @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/intersectionReductionGenericStringLikeType.ts] //// + +=== intersectionReductionGenericStringLikeType.ts === +// https://github.com/microsoft/TypeScript/issues/57736 + +type obj = { +>obj : { foo: 1; bar: 2; } + + foo: 1; +>foo : 1 + + bar: 2; +>bar : 2 + +}; + +type keyContaining1< +>keyContaining1 : keyContaining1 + + str extends string, + keys extends keyof obj = keyof obj, +> = keys extends infer key extends keyof obj + ? key extends `${string}${str}${string}` + ? obj[key] + : never + : never; + +type _1 = keyContaining1<"foo">; // 1 +>_1 : 1 + +type keyContaining2< +>keyContaining2 : keyContaining2 + + str extends string, + keys extends keyof obj = keyof obj, +> = keys extends keys + ? keys extends `${string}${str}${string}` + ? obj[keys] + : never + : never; + +type _2 = keyContaining2<"foo">; // 1 +>_2 : 1 + diff --git a/tests/cases/compiler/intersectionReductionGenericStringLikeType.ts b/tests/cases/compiler/intersectionReductionGenericStringLikeType.ts new file mode 100644 index 0000000000000..c59a4321d074d --- /dev/null +++ b/tests/cases/compiler/intersectionReductionGenericStringLikeType.ts @@ -0,0 +1,31 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/57736 + +type obj = { + foo: 1; + bar: 2; +}; + +type keyContaining1< + str extends string, + keys extends keyof obj = keyof obj, +> = keys extends infer key extends keyof obj + ? key extends `${string}${str}${string}` + ? obj[key] + : never + : never; + +type _1 = keyContaining1<"foo">; // 1 + +type keyContaining2< + str extends string, + keys extends keyof obj = keyof obj, +> = keys extends keys + ? keys extends `${string}${str}${string}` + ? obj[keys] + : never + : never; + +type _2 = keyContaining2<"foo">; // 1 From 485c7c5d08f985528a83d9879658912181ef7f11 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 15 Mar 2024 12:26:01 -0700 Subject: [PATCH 02/10] =?UTF-8?q?Revert=20"Allow=20(non-assert)=20type=20p?= =?UTF-8?q?redicates=20to=20narrow=20by=20discriminant"=E2=80=A6=20(#57795?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/checker.ts | 98 ++++++------- src/compiler/commandLineParser.ts | 1 + .../discriminantNarrowingCouldBeCircular.js | 69 +++++++++ ...scriminantNarrowingCouldBeCircular.symbols | 129 ++++++++++++++++ ...discriminantNarrowingCouldBeCircular.types | 138 ++++++++++++++++++ ...ePredicatesCanNarrowByDiscriminant.symbols | 8 +- ...ypePredicatesCanNarrowByDiscriminant.types | 12 +- .../discriminantNarrowingCouldBeCircular.ts | 40 +++++ 8 files changed, 434 insertions(+), 61 deletions(-) create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.js create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.types create mode 100644 tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 583c4827e63c8..cf16285cdb1a8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26741,11 +26741,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function hasMatchingArgument(expression: CallExpression | NewExpression, reference: Node) { if (expression.arguments) { for (const argument of expression.arguments) { - if ( - isOrContainsMatchingReference(reference, argument) - || optionalChainContainsReference(argument, reference) - || getCandidateDiscriminantPropertyAccess(argument, reference) - ) { + if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference)) { return true; } } @@ -26759,51 +26755,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function getCandidateDiscriminantPropertyAccess(expr: Expression, reference: Node) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { - // When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in - // getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or - // parameter declared in the same parameter list is a candidate. - if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - const declaration = symbol.valueDeclaration; - if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { - return declaration; - } - } - } - else if (isAccessExpression(expr)) { - // An access expression is a candidate if the reference matches the left hand expression. - if (isMatchingReference(reference, expr.expression)) { - return expr; - } - } - else if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - if (isConstantVariable(symbol)) { - const declaration = symbol.valueDeclaration!; - // Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind' - if ( - isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && - isMatchingReference(reference, declaration.initializer.expression) - ) { - return declaration.initializer; - } - // Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind' - if (isBindingElement(declaration) && !declaration.initializer) { - const parent = declaration.parent.parent; - if ( - isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) && - isMatchingReference(reference, parent.initializer) - ) { - return declaration; - } - } - } - } - return undefined; - } - function getFlowNodeId(flow: FlowNode): number { if (!flow.id || flow.id < 0) { flow.id = nextFlowId; @@ -28160,12 +28111,57 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } + function getCandidateDiscriminantPropertyAccess(expr: Expression) { + if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { + // When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in + // getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or + // parameter declared in the same parameter list is a candidate. + if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + const declaration = symbol.valueDeclaration; + if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { + return declaration; + } + } + } + else if (isAccessExpression(expr)) { + // An access expression is a candidate if the reference matches the left hand expression. + if (isMatchingReference(reference, expr.expression)) { + return expr; + } + } + else if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + if (isConstantVariable(symbol)) { + const declaration = symbol.valueDeclaration!; + // Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind' + if ( + isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && + isMatchingReference(reference, declaration.initializer.expression) + ) { + return declaration.initializer; + } + // Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind' + if (isBindingElement(declaration) && !declaration.initializer) { + const parent = declaration.parent.parent; + if ( + isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) && + isMatchingReference(reference, parent.initializer) + ) { + return declaration; + } + } + } + } + return undefined; + } + function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) { // As long as the computed type is a subset of the declared type, we use the full declared type to detect // a discriminant property. In cases where the computed type isn't a subset, e.g because of a preceding type // predicate narrowing, we use the actual computed type. if (declaredType.flags & TypeFlags.Union || computedType.flags & TypeFlags.Union) { - const access = getCandidateDiscriminantPropertyAccess(expr, reference); + const access = getCandidateDiscriminantPropertyAccess(expr); if (access) { const name = getAccessedPropertyName(access); if (name) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index feee1493eb16a..d513c5793dadf 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -3505,6 +3505,7 @@ export function convertJsonOption( convertJsonOption(opt.element, value, basePath, errors, propertyAssignment, valueExpression, sourceFile); } else if (!isString(opt.type)) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion return convertJsonOptionOfCustomType(opt as CommandLineOptionOfCustomType, value as string, errors, valueExpression, sourceFile); } const validatedValue = validateJsonOptionValue(opt, value, errors, valueExpression, sourceFile); diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js new file mode 100644 index 0000000000000..2cc50e16b98cd --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js @@ -0,0 +1,69 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +//// [discriminantNarrowingCouldBeCircular.ts] +// #57705, 57690 +declare function is(v: T): v is T; +const o: Record | undefined = {}; +if (o) { + for (const key in o) { + const value = o[key]; + if (is(value)) { + } + } +} + +type SomeRecord = { a: string }; +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +declare function parentElementOrShadowHost(element: SomeRecord): SomeRecord | undefined; + +function getImplicitAriaRole(element: SomeRecord) { + let ancestor: SomeRecord | null = element; + while (ancestor) { + const parent = parentElementOrShadowHost(ancestor); + const parents = kPresentationInheritanceParents[ancestor.a]; + if (!parents || !parent || !parents.includes(parent.a)) + break; + ancestor = parent; + } +} + +declare function isPlainObject2( + data: unknown, + ): data is Record; + + declare const myObj2: unknown; + if (isPlainObject2(myObj2)) { + for (const key of ["a", "b", "c"]) { + const deeper = myObj2[key]; + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } + } + + +//// [discriminantNarrowingCouldBeCircular.js] +"use strict"; +var o = {}; +if (o) { + for (var key in o) { + var value = o[key]; + if (is(value)) { + } + } +} +function getImplicitAriaRole(element) { + var ancestor = element; + while (ancestor) { + var parent = parentElementOrShadowHost(ancestor); + var parents = kPresentationInheritanceParents[ancestor.a]; + if (!parents || !parent || !parents.includes(parent.a)) + break; + ancestor = parent; + } +} +if (isPlainObject2(myObj2)) { + for (var _i = 0, _a = ["a", "b", "c"]; _i < _a.length; _i++) { + var key = _a[_i]; + var deeper = myObj2[key]; + var deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } +} diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols new file mode 100644 index 0000000000000..63c7e9dc7f5af --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols @@ -0,0 +1,129 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +=== discriminantNarrowingCouldBeCircular.ts === +// #57705, 57690 +declare function is(v: T): v is T; +>is : Symbol(is, Decl(discriminantNarrowingCouldBeCircular.ts, 0, 0)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) +>v : Symbol(v, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 23)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) +>v : Symbol(v, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 23)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) + +const o: Record | undefined = {}; +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +if (o) { +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) + + for (const key in o) { +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 4, 12)) +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) + + const value = o[key]; +>value : Symbol(value, Decl(discriminantNarrowingCouldBeCircular.ts, 5, 9)) +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 4, 12)) + + if (is(value)) { +>is : Symbol(is, Decl(discriminantNarrowingCouldBeCircular.ts, 0, 0)) +>value : Symbol(value, Decl(discriminantNarrowingCouldBeCircular.ts, 5, 9)) + } + } +} + +type SomeRecord = { a: string }; +>SomeRecord : Symbol(SomeRecord, Decl(discriminantNarrowingCouldBeCircular.ts, 9, 1)) +>a : Symbol(a, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 19)) + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +>kPresentationInheritanceParents : Symbol(kPresentationInheritanceParents, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 13)) +>tagName : Symbol(tagName, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 50)) + +declare function parentElementOrShadowHost(element: SomeRecord): SomeRecord | undefined; +>parentElementOrShadowHost : Symbol(parentElementOrShadowHost, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 79)) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 13, 43)) +>SomeRecord : Symbol(SomeRecord, Decl(discriminantNarrowingCouldBeCircular.ts, 9, 1)) +>SomeRecord : Symbol(SomeRecord, Decl(discriminantNarrowingCouldBeCircular.ts, 9, 1)) + +function getImplicitAriaRole(element: SomeRecord) { +>getImplicitAriaRole : Symbol(getImplicitAriaRole, Decl(discriminantNarrowingCouldBeCircular.ts, 13, 88)) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 29)) +>SomeRecord : Symbol(SomeRecord, Decl(discriminantNarrowingCouldBeCircular.ts, 9, 1)) + + let ancestor: SomeRecord | null = element; +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 16, 5)) +>SomeRecord : Symbol(SomeRecord, Decl(discriminantNarrowingCouldBeCircular.ts, 9, 1)) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 29)) + + while (ancestor) { +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 16, 5)) + + const parent = parentElementOrShadowHost(ancestor); +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>parentElementOrShadowHost : Symbol(parentElementOrShadowHost, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 79)) +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 16, 5)) + + const parents = kPresentationInheritanceParents[ancestor.a]; +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 19, 9)) +>kPresentationInheritanceParents : Symbol(kPresentationInheritanceParents, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 13)) +>ancestor.a : Symbol(a, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 19)) +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 16, 5)) +>a : Symbol(a, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 19)) + + if (!parents || !parent || !parents.includes(parent.a)) +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 19, 9)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>parents.includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 19, 9)) +>includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>parent.a : Symbol(a, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 19)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>a : Symbol(a, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 19)) + + break; + ancestor = parent; +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 16, 5)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) + } +} + +declare function isPlainObject2( +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 24, 1)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 26, 32)) + + data: unknown, +>data : Symbol(data, Decl(discriminantNarrowingCouldBeCircular.ts, 26, 35)) + + ): data is Record; +>data : Symbol(data, Decl(discriminantNarrowingCouldBeCircular.ts, 26, 35)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --)) + + declare const myObj2: unknown; +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 30, 15)) + + if (isPlainObject2(myObj2)) { +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 24, 1)) +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 30, 15)) + + for (const key of ["a", "b", "c"]) { +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 32, 16)) + + const deeper = myObj2[key]; +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 33, 13)) +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 30, 15)) +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 32, 16)) + + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; +>deeperKeys : Symbol(deeperKeys, Decl(discriminantNarrowingCouldBeCircular.ts, 34, 13)) +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 24, 1)) +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 33, 13)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 33, 13)) + } + } + diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types new file mode 100644 index 0000000000000..63b27fb6c352a --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types @@ -0,0 +1,138 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +=== discriminantNarrowingCouldBeCircular.ts === +// #57705, 57690 +declare function is(v: T): v is T; +>is : (v: T) => v is T +>v : T + +const o: Record | undefined = {}; +>o : Record | undefined +>{} : {} + +if (o) { +>o : Record + + for (const key in o) { +>key : string +>o : Record + + const value = o[key]; +>value : string +>o[key] : string +>o : Record +>key : string + + if (is(value)) { +>is(value) : boolean +>is : (v: T) => v is T +>value : string + } + } +} + +type SomeRecord = { a: string }; +>SomeRecord : { a: string; } +>a : string + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +>kPresentationInheritanceParents : { [tagName: string]: string[]; } +>tagName : string + +declare function parentElementOrShadowHost(element: SomeRecord): SomeRecord | undefined; +>parentElementOrShadowHost : (element: SomeRecord) => SomeRecord | undefined +>element : SomeRecord + +function getImplicitAriaRole(element: SomeRecord) { +>getImplicitAriaRole : (element: SomeRecord) => void +>element : SomeRecord + + let ancestor: SomeRecord | null = element; +>ancestor : SomeRecord | null +>element : SomeRecord + + while (ancestor) { +>ancestor : SomeRecord + + const parent = parentElementOrShadowHost(ancestor); +>parent : SomeRecord | undefined +>parentElementOrShadowHost(ancestor) : SomeRecord | undefined +>parentElementOrShadowHost : (element: SomeRecord) => SomeRecord | undefined +>ancestor : SomeRecord + + const parents = kPresentationInheritanceParents[ancestor.a]; +>parents : string[] +>kPresentationInheritanceParents[ancestor.a] : string[] +>kPresentationInheritanceParents : { [tagName: string]: string[]; } +>ancestor.a : string +>ancestor : SomeRecord +>a : string + + if (!parents || !parent || !parents.includes(parent.a)) +>!parents || !parent || !parents.includes(parent.a) : boolean +>!parents || !parent : boolean +>!parents : false +>parents : string[] +>!parent : boolean +>parent : SomeRecord | undefined +>!parents.includes(parent.a) : boolean +>parents.includes(parent.a) : boolean +>parents.includes : (searchElement: string, fromIndex?: number | undefined) => boolean +>parents : string[] +>includes : (searchElement: string, fromIndex?: number | undefined) => boolean +>parent.a : string +>parent : SomeRecord +>a : string + + break; + ancestor = parent; +>ancestor = parent : SomeRecord +>ancestor : SomeRecord | null +>parent : SomeRecord + } +} + +declare function isPlainObject2( +>isPlainObject2 : (data: unknown) => data is Record + + data: unknown, +>data : unknown + + ): data is Record; + + declare const myObj2: unknown; +>myObj2 : unknown + + if (isPlainObject2(myObj2)) { +>isPlainObject2(myObj2) : boolean +>isPlainObject2 : (data: unknown) => data is Record +>myObj2 : unknown + + for (const key of ["a", "b", "c"]) { +>key : string +>["a", "b", "c"] : string[] +>"a" : "a" +>"b" : "b" +>"c" : "c" + + const deeper = myObj2[key]; +>deeper : unknown +>myObj2[key] : unknown +>myObj2 : Record +>key : string + + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; +>deeperKeys : string[] +>isPlainObject2(deeper) ? Object.keys(deeper) : [] : string[] +>isPlainObject2(deeper) : boolean +>isPlainObject2 : (data: unknown) => data is Record +>deeper : unknown +>Object.keys(deeper) : string[] +>Object.keys : { (o: object): string[]; (o: {}): string[]; } +>Object : ObjectConstructor +>keys : { (o: object): string[]; (o: {}): string[]; } +>deeper : Record +>[] : never[] + } + } + diff --git a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols index e1bacc007b26a..6c33043410585 100644 --- a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols +++ b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols @@ -28,9 +28,9 @@ if (isOneOf(fruit.kind, ['apple', 'banana'] as const)) { >const : Symbol(const) fruit.kind ->fruit.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41)) +>fruit.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 62)) >fruit : Symbol(fruit, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 13)) ->kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41)) +>kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 62)) fruit >fruit : Symbol(fruit, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 13)) @@ -54,9 +54,9 @@ if (isOneOf(kind, ['apple', 'banana'] as const)) { >const : Symbol(const) fruit2.kind ->fruit2.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42)) +>fruit2.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 63)) >fruit2 : Symbol(fruit2, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 13)) ->kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42)) +>kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 63)) fruit2 >fruit2 : Symbol(fruit2, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 13)) diff --git a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types index 3dc7156b1fa08..bc14536bc8c5f 100644 --- a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types +++ b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types @@ -26,11 +26,11 @@ if (isOneOf(fruit.kind, ['apple', 'banana'] as const)) { fruit.kind >fruit.kind : "apple" | "banana" ->fruit : { kind: "apple"; } | { kind: "banana"; } +>fruit : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } >kind : "apple" | "banana" fruit ->fruit : { kind: "apple"; } | { kind: "banana"; } +>fruit : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } } declare const fruit2: { kind: 'apple'} | { kind: 'banana' } | { kind: 'cherry' } @@ -55,10 +55,10 @@ if (isOneOf(kind, ['apple', 'banana'] as const)) { >'banana' : "banana" fruit2.kind ->fruit2.kind : "apple" | "banana" ->fruit2 : { kind: "apple"; } | { kind: "banana"; } ->kind : "apple" | "banana" +>fruit2.kind : "apple" | "banana" | "cherry" +>fruit2 : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } +>kind : "apple" | "banana" | "cherry" fruit2 ->fruit2 : { kind: "apple"; } | { kind: "banana"; } +>fruit2 : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } } diff --git a/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts b/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts new file mode 100644 index 0000000000000..1c85d9e757307 --- /dev/null +++ b/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts @@ -0,0 +1,40 @@ +// @strict: true +// @lib: es2022 + +// #57705, 57690 +declare function is(v: T): v is T; +const o: Record | undefined = {}; +if (o) { + for (const key in o) { + const value = o[key]; + if (is(value)) { + } + } +} + +type SomeRecord = { a: string }; +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +declare function parentElementOrShadowHost(element: SomeRecord): SomeRecord | undefined; + +function getImplicitAriaRole(element: SomeRecord) { + let ancestor: SomeRecord | null = element; + while (ancestor) { + const parent = parentElementOrShadowHost(ancestor); + const parents = kPresentationInheritanceParents[ancestor.a]; + if (!parents || !parent || !parents.includes(parent.a)) + break; + ancestor = parent; + } +} + +declare function isPlainObject2( + data: unknown, + ): data is Record; + + declare const myObj2: unknown; + if (isPlainObject2(myObj2)) { + for (const key of ["a", "b", "c"]) { + const deeper = myObj2[key]; + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } + } From f42605fcef04f329e9bb5cb94677ca0101dcdd5c Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 15 Mar 2024 12:28:48 -0700 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#57746=20(Reve?= =?UTF-8?q?rt=20"Defer=20processing=20of=20nested=20...)=20into=20release-?= =?UTF-8?q?5.4=20(#57752)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> --- src/compiler/checker.ts | 10 +-- ...ericNestedCallReturningConstructor.symbols | 72 ------------------- ...enericNestedCallReturningConstructor.types | 63 ---------------- ...ceGenericNestedCallReturningConstructor.ts | 28 -------- 4 files changed, 3 insertions(+), 170 deletions(-) delete mode 100644 tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols delete mode 100644 tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types delete mode 100644 tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cf16285cdb1a8..3981ebc1255ff 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35136,7 +35136,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // use the resolvingSignature singleton to indicate that we deferred processing. This result will be // propagated out and eventually turned into silentNeverType (a type that is assignable to anything and // from which we never make inferences). - if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) { + if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { skippedGenericFunction(node, checkMode); return resolvingSignature; } @@ -35149,12 +35149,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunctionOrConstructor(signature: Signature) { - if (!signature.typeParameters) { - return false; - } - const returnType = getReturnTypeOfSignature(signature); - return isFunctionType(returnType) || isConstructorType(returnType); + function isGenericFunctionReturningFunction(signature: Signature) { + return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); } /** diff --git a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols deleted file mode 100644 index 03e0bcb9f168b..0000000000000 --- a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.symbols +++ /dev/null @@ -1,72 +0,0 @@ -//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] //// - -=== inferenceGenericNestedCallReturningConstructor.ts === -interface Action { ->Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17)) - - new (ctx: TContext): void; ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 1, 7)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17)) -} - -declare class AssignAction { ->AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27)) - - constructor(ctx: TContext); ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 5, 14)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27)) -} - -declare function assign( ->assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) - - assigner: (ctx: TContext) => void ->assigner : Symbol(assigner, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 34)) ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 9, 13)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) - -): { - new (ctx: TContext): AssignAction; ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 11, 7)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) ->AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24)) -} - -declare function createMachine(config: { ->createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) ->config : Symbol(config, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 41)) - - context: TContext; ->context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 50)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) - - entry: Action; ->entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 15, 20)) ->Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0)) ->TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31)) - -}): void; - -createMachine({ ->createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1)) - - context: { count: 0 }, ->context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 19, 15)) ->count : Symbol(count, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 12)) - - entry: assign((ctx) => { ->entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 24)) ->assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1)) ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17)) - - ctx // { count: number } ->ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17)) - - }), -}); - diff --git a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types b/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types deleted file mode 100644 index ce6d09b4d3281..0000000000000 --- a/tests/baselines/reference/inferenceGenericNestedCallReturningConstructor.types +++ /dev/null @@ -1,63 +0,0 @@ -//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] //// - -=== inferenceGenericNestedCallReturningConstructor.ts === -interface Action { - new (ctx: TContext): void; ->ctx : TContext -} - -declare class AssignAction { ->AssignAction : AssignAction - - constructor(ctx: TContext); ->ctx : TContext -} - -declare function assign( ->assign : (assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction - - assigner: (ctx: TContext) => void ->assigner : (ctx: TContext) => void ->ctx : TContext - -): { - new (ctx: TContext): AssignAction; ->ctx : TContext -} - -declare function createMachine(config: { ->createMachine : (config: { context: TContext; entry: Action;}) => void ->config : { context: TContext; entry: Action; } - - context: TContext; ->context : TContext - - entry: Action; ->entry : Action - -}): void; - -createMachine({ ->createMachine({ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),}) : void ->createMachine : (config: { context: TContext; entry: Action; }) => void ->{ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),} : { context: { count: number; }; entry: new (ctx: { count: number; }) => AssignAction<{ count: number; }>; } - - context: { count: 0 }, ->context : { count: number; } ->{ count: 0 } : { count: number; } ->count : number ->0 : 0 - - entry: assign((ctx) => { ->entry : new (ctx: { count: number; }) => AssignAction<{ count: number; }> ->assign((ctx) => { ctx // { count: number } }) : new (ctx: { count: number; }) => AssignAction<{ count: number; }> ->assign : (assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction ->(ctx) => { ctx // { count: number } } : (ctx: { count: number; }) => void ->ctx : { count: number; } - - ctx // { count: number } ->ctx : { count: number; } - - }), -}); - diff --git a/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts b/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts deleted file mode 100644 index 8c1ea32096284..0000000000000 --- a/tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts +++ /dev/null @@ -1,28 +0,0 @@ -// @strict: true -// @noEmit: true - -interface Action { - new (ctx: TContext): void; -} - -declare class AssignAction { - constructor(ctx: TContext); -} - -declare function assign( - assigner: (ctx: TContext) => void -): { - new (ctx: TContext): AssignAction; -} - -declare function createMachine(config: { - context: TContext; - entry: Action; -}): void; - -createMachine({ - context: { count: 0 }, - entry: assign((ctx) => { - ctx // { count: number } - }), -}); From 609560f36b84bf031fa14cc4b0d1b2aeb8cfc6f9 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 15 Mar 2024 19:40:24 +0000 Subject: [PATCH 04/10] Bump version to 5.4.3 and LKG --- lib/tsc.js | 83 +++++++++++++++++++------------------- lib/tsserver.js | 83 +++++++++++++++++++------------------- lib/typescript.js | 83 +++++++++++++++++++------------------- lib/typingsInstaller.js | 2 +- package-lock.json | 4 +- package.json | 2 +- src/compiler/corePublic.ts | 2 +- 7 files changed, 128 insertions(+), 131 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index b78d968065015..f3f3150c5d65b 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -18,7 +18,7 @@ and limitations under the License. // src/compiler/corePublic.ts var versionMajorMinor = "5.4"; -var version = "5.4.2"; +var version = "5.4.3"; // src/compiler/core.ts var emptyArray = []; @@ -57966,7 +57966,7 @@ function createTypeChecker(host) { const typeVarIndex = typeSet[0].flags & 8650752 /* TypeVariable */ ? 0 : 1; const typeVariable = typeSet[typeVarIndex]; const primitiveType = typeSet[1 - typeVarIndex]; - if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) || includes & 16777216 /* IncludesEmptyObject */)) { + if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) && !isGenericStringLikeType(primitiveType) || includes & 16777216 /* IncludesEmptyObject */)) { const constraint = getBaseConstraintOfType(typeVariable); if (constraint && everyType(constraint, (t) => !!(t.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */)) || isEmptyAnonymousObjectType(t))) { if (isTypeStrictSubtypeOf(constraint, primitiveType)) { @@ -58574,6 +58574,9 @@ function createTypeChecker(host) { function isPatternLiteralType(type) { return !!(type.flags & 134217728 /* TemplateLiteral */) && every(type.types, isPatternLiteralPlaceholderType) || !!(type.flags & 268435456 /* StringMapping */) && isPatternLiteralPlaceholderType(type.type); } + function isGenericStringLikeType(type) { + return !!(type.flags & (134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */)) && !isPatternLiteralType(type); + } function isGenericType(type) { return !!getGenericObjectFlags(type); } @@ -58596,7 +58599,7 @@ function createTypeChecker(host) { } return type.objectFlags & 12582912 /* IsGenericType */; } - return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */ | 134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */) && !isPatternLiteralType(type) ? 8388608 /* IsGenericIndexType */ : 0); + return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */) || isGenericStringLikeType(type) ? 8388608 /* IsGenericIndexType */ : 0); } function getSimplifiedType(type, writing) { return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) : type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) : type; @@ -65644,7 +65647,7 @@ function createTypeChecker(host) { function hasMatchingArgument(expression, reference) { if (expression.arguments) { for (const argument of expression.arguments) { - if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference) || getCandidateDiscriminantPropertyAccess(argument, reference)) { + if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference)) { return true; } } @@ -65654,36 +65657,6 @@ function createTypeChecker(host) { } return false; } - function getCandidateDiscriminantPropertyAccess(expr, reference) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { - if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - const declaration = symbol.valueDeclaration; - if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { - return declaration; - } - } - } else if (isAccessExpression(expr)) { - if (isMatchingReference(reference, expr.expression)) { - return expr; - } - } else if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - if (isConstantVariable(symbol)) { - const declaration = symbol.valueDeclaration; - if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { - return declaration.initializer; - } - if (isBindingElement(declaration) && !declaration.initializer) { - const parent = declaration.parent.parent; - if (isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) && isMatchingReference(reference, parent.initializer)) { - return declaration; - } - } - } - } - return void 0; - } function getFlowNodeId(flow) { if (!flow.id || flow.id < 0) { flow.id = nextFlowId; @@ -66783,9 +66756,39 @@ function createTypeChecker(host) { } return result; } + function getCandidateDiscriminantPropertyAccess(expr) { + if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { + if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + const declaration = symbol.valueDeclaration; + if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { + return declaration; + } + } + } else if (isAccessExpression(expr)) { + if (isMatchingReference(reference, expr.expression)) { + return expr; + } + } else if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + if (isConstantVariable(symbol)) { + const declaration = symbol.valueDeclaration; + if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { + return declaration.initializer; + } + if (isBindingElement(declaration) && !declaration.initializer) { + const parent = declaration.parent.parent; + if (isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) && isMatchingReference(reference, parent.initializer)) { + return declaration; + } + } + } + } + return void 0; + } function getDiscriminantPropertyAccess(expr, computedType) { if (declaredType.flags & 1048576 /* Union */ || computedType.flags & 1048576 /* Union */) { - const access = getCandidateDiscriminantPropertyAccess(expr, reference); + const access = getCandidateDiscriminantPropertyAccess(expr); if (access) { const name = getAccessedPropertyName(access); if (name) { @@ -72506,7 +72509,7 @@ function createTypeChecker(host) { } return resolveErrorCall(node); } - if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) { + if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { skippedGenericFunction(node, checkMode); return resolvingSignature; } @@ -72516,12 +72519,8 @@ function createTypeChecker(host) { } return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunctionOrConstructor(signature) { - if (!signature.typeParameters) { - return false; - } - const returnType = getReturnTypeOfSignature(signature); - return isFunctionType(returnType) || isConstructorType(returnType); + function isGenericFunctionReturningFunction(signature) { + return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); } function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) { return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) || !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & 1048576 /* Union */) && !(getReducedType(apparentFuncType).flags & 131072 /* Never */) && isTypeAssignableTo(funcType, globalFunctionType); diff --git a/lib/tsserver.js b/lib/tsserver.js index dacf281c309e2..df1f3dd752ab6 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -2340,7 +2340,7 @@ module.exports = __toCommonJS(server_exports); // src/compiler/corePublic.ts var versionMajorMinor = "5.4"; -var version = "5.4.2"; +var version = "5.4.3"; var Comparison = /* @__PURE__ */ ((Comparison3) => { Comparison3[Comparison3["LessThan"] = -1] = "LessThan"; Comparison3[Comparison3["EqualTo"] = 0] = "EqualTo"; @@ -62710,7 +62710,7 @@ function createTypeChecker(host) { const typeVarIndex = typeSet[0].flags & 8650752 /* TypeVariable */ ? 0 : 1; const typeVariable = typeSet[typeVarIndex]; const primitiveType = typeSet[1 - typeVarIndex]; - if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) || includes & 16777216 /* IncludesEmptyObject */)) { + if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) && !isGenericStringLikeType(primitiveType) || includes & 16777216 /* IncludesEmptyObject */)) { const constraint = getBaseConstraintOfType(typeVariable); if (constraint && everyType(constraint, (t) => !!(t.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */)) || isEmptyAnonymousObjectType(t))) { if (isTypeStrictSubtypeOf(constraint, primitiveType)) { @@ -63318,6 +63318,9 @@ function createTypeChecker(host) { function isPatternLiteralType(type) { return !!(type.flags & 134217728 /* TemplateLiteral */) && every(type.types, isPatternLiteralPlaceholderType) || !!(type.flags & 268435456 /* StringMapping */) && isPatternLiteralPlaceholderType(type.type); } + function isGenericStringLikeType(type) { + return !!(type.flags & (134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */)) && !isPatternLiteralType(type); + } function isGenericType(type) { return !!getGenericObjectFlags(type); } @@ -63340,7 +63343,7 @@ function createTypeChecker(host) { } return type.objectFlags & 12582912 /* IsGenericType */; } - return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */ | 134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */) && !isPatternLiteralType(type) ? 8388608 /* IsGenericIndexType */ : 0); + return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */) || isGenericStringLikeType(type) ? 8388608 /* IsGenericIndexType */ : 0); } function getSimplifiedType(type, writing) { return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) : type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) : type; @@ -70388,7 +70391,7 @@ function createTypeChecker(host) { function hasMatchingArgument(expression, reference) { if (expression.arguments) { for (const argument of expression.arguments) { - if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference) || getCandidateDiscriminantPropertyAccess(argument, reference)) { + if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference)) { return true; } } @@ -70398,36 +70401,6 @@ function createTypeChecker(host) { } return false; } - function getCandidateDiscriminantPropertyAccess(expr, reference) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { - if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - const declaration = symbol.valueDeclaration; - if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { - return declaration; - } - } - } else if (isAccessExpression(expr)) { - if (isMatchingReference(reference, expr.expression)) { - return expr; - } - } else if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - if (isConstantVariable(symbol)) { - const declaration = symbol.valueDeclaration; - if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { - return declaration.initializer; - } - if (isBindingElement(declaration) && !declaration.initializer) { - const parent2 = declaration.parent.parent; - if (isVariableDeclaration(parent2) && !parent2.type && parent2.initializer && (isIdentifier(parent2.initializer) || isAccessExpression(parent2.initializer)) && isMatchingReference(reference, parent2.initializer)) { - return declaration; - } - } - } - } - return void 0; - } function getFlowNodeId(flow) { if (!flow.id || flow.id < 0) { flow.id = nextFlowId; @@ -71527,9 +71500,39 @@ function createTypeChecker(host) { } return result; } + function getCandidateDiscriminantPropertyAccess(expr) { + if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { + if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + const declaration = symbol.valueDeclaration; + if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { + return declaration; + } + } + } else if (isAccessExpression(expr)) { + if (isMatchingReference(reference, expr.expression)) { + return expr; + } + } else if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + if (isConstantVariable(symbol)) { + const declaration = symbol.valueDeclaration; + if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { + return declaration.initializer; + } + if (isBindingElement(declaration) && !declaration.initializer) { + const parent2 = declaration.parent.parent; + if (isVariableDeclaration(parent2) && !parent2.type && parent2.initializer && (isIdentifier(parent2.initializer) || isAccessExpression(parent2.initializer)) && isMatchingReference(reference, parent2.initializer)) { + return declaration; + } + } + } + } + return void 0; + } function getDiscriminantPropertyAccess(expr, computedType) { if (declaredType.flags & 1048576 /* Union */ || computedType.flags & 1048576 /* Union */) { - const access = getCandidateDiscriminantPropertyAccess(expr, reference); + const access = getCandidateDiscriminantPropertyAccess(expr); if (access) { const name = getAccessedPropertyName(access); if (name) { @@ -77250,7 +77253,7 @@ function createTypeChecker(host) { } return resolveErrorCall(node); } - if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) { + if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { skippedGenericFunction(node, checkMode); return resolvingSignature; } @@ -77260,12 +77263,8 @@ function createTypeChecker(host) { } return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunctionOrConstructor(signature) { - if (!signature.typeParameters) { - return false; - } - const returnType = getReturnTypeOfSignature(signature); - return isFunctionType(returnType) || isConstructorType(returnType); + function isGenericFunctionReturningFunction(signature) { + return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); } function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) { return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) || !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & 1048576 /* Union */) && !(getReducedType(apparentFuncType).flags & 131072 /* Never */) && isTypeAssignableTo(funcType, globalFunctionType); diff --git a/lib/typescript.js b/lib/typescript.js index adde21acf1e4f..05672d241e67b 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -35,7 +35,7 @@ var ts = (() => { "src/compiler/corePublic.ts"() { "use strict"; versionMajorMinor = "5.4"; - version = "5.4.2"; + version = "5.4.3"; Comparison = /* @__PURE__ */ ((Comparison3) => { Comparison3[Comparison3["LessThan"] = -1] = "LessThan"; Comparison3[Comparison3["EqualTo"] = 0] = "EqualTo"; @@ -60465,7 +60465,7 @@ ${lanes.join("\n")} const typeVarIndex = typeSet[0].flags & 8650752 /* TypeVariable */ ? 0 : 1; const typeVariable = typeSet[typeVarIndex]; const primitiveType = typeSet[1 - typeVarIndex]; - if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) || includes & 16777216 /* IncludesEmptyObject */)) { + if (typeVariable.flags & 8650752 /* TypeVariable */ && (primitiveType.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */) && !isGenericStringLikeType(primitiveType) || includes & 16777216 /* IncludesEmptyObject */)) { const constraint = getBaseConstraintOfType(typeVariable); if (constraint && everyType(constraint, (t) => !!(t.flags & (402784252 /* Primitive */ | 67108864 /* NonPrimitive */)) || isEmptyAnonymousObjectType(t))) { if (isTypeStrictSubtypeOf(constraint, primitiveType)) { @@ -61073,6 +61073,9 @@ ${lanes.join("\n")} function isPatternLiteralType(type) { return !!(type.flags & 134217728 /* TemplateLiteral */) && every(type.types, isPatternLiteralPlaceholderType) || !!(type.flags & 268435456 /* StringMapping */) && isPatternLiteralPlaceholderType(type.type); } + function isGenericStringLikeType(type) { + return !!(type.flags & (134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */)) && !isPatternLiteralType(type); + } function isGenericType(type) { return !!getGenericObjectFlags(type); } @@ -61095,7 +61098,7 @@ ${lanes.join("\n")} } return type.objectFlags & 12582912 /* IsGenericType */; } - return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */ | 134217728 /* TemplateLiteral */ | 268435456 /* StringMapping */) && !isPatternLiteralType(type) ? 8388608 /* IsGenericIndexType */ : 0); + return (type.flags & 58982400 /* InstantiableNonPrimitive */ || isGenericMappedType(type) || isGenericTupleType(type) ? 4194304 /* IsGenericObjectType */ : 0) | (type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */) || isGenericStringLikeType(type) ? 8388608 /* IsGenericIndexType */ : 0); } function getSimplifiedType(type, writing) { return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) : type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) : type; @@ -68143,7 +68146,7 @@ ${lanes.join("\n")} function hasMatchingArgument(expression, reference) { if (expression.arguments) { for (const argument of expression.arguments) { - if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference) || getCandidateDiscriminantPropertyAccess(argument, reference)) { + if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference)) { return true; } } @@ -68153,36 +68156,6 @@ ${lanes.join("\n")} } return false; } - function getCandidateDiscriminantPropertyAccess(expr, reference) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { - if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - const declaration = symbol.valueDeclaration; - if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { - return declaration; - } - } - } else if (isAccessExpression(expr)) { - if (isMatchingReference(reference, expr.expression)) { - return expr; - } - } else if (isIdentifier(expr)) { - const symbol = getResolvedSymbol(expr); - if (isConstantVariable(symbol)) { - const declaration = symbol.valueDeclaration; - if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { - return declaration.initializer; - } - if (isBindingElement(declaration) && !declaration.initializer) { - const parent2 = declaration.parent.parent; - if (isVariableDeclaration(parent2) && !parent2.type && parent2.initializer && (isIdentifier(parent2.initializer) || isAccessExpression(parent2.initializer)) && isMatchingReference(reference, parent2.initializer)) { - return declaration; - } - } - } - } - return void 0; - } function getFlowNodeId(flow) { if (!flow.id || flow.id < 0) { flow.id = nextFlowId; @@ -69282,9 +69255,39 @@ ${lanes.join("\n")} } return result; } + function getCandidateDiscriminantPropertyAccess(expr) { + if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { + if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + const declaration = symbol.valueDeclaration; + if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) { + return declaration; + } + } + } else if (isAccessExpression(expr)) { + if (isMatchingReference(reference, expr.expression)) { + return expr; + } + } else if (isIdentifier(expr)) { + const symbol = getResolvedSymbol(expr); + if (isConstantVariable(symbol)) { + const declaration = symbol.valueDeclaration; + if (isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) && isMatchingReference(reference, declaration.initializer.expression)) { + return declaration.initializer; + } + if (isBindingElement(declaration) && !declaration.initializer) { + const parent2 = declaration.parent.parent; + if (isVariableDeclaration(parent2) && !parent2.type && parent2.initializer && (isIdentifier(parent2.initializer) || isAccessExpression(parent2.initializer)) && isMatchingReference(reference, parent2.initializer)) { + return declaration; + } + } + } + } + return void 0; + } function getDiscriminantPropertyAccess(expr, computedType) { if (declaredType.flags & 1048576 /* Union */ || computedType.flags & 1048576 /* Union */) { - const access = getCandidateDiscriminantPropertyAccess(expr, reference); + const access = getCandidateDiscriminantPropertyAccess(expr); if (access) { const name = getAccessedPropertyName(access); if (name) { @@ -75005,7 +75008,7 @@ ${lanes.join("\n")} } return resolveErrorCall(node); } - if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) { + if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { skippedGenericFunction(node, checkMode); return resolvingSignature; } @@ -75015,12 +75018,8 @@ ${lanes.join("\n")} } return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } - function isGenericFunctionReturningFunctionOrConstructor(signature) { - if (!signature.typeParameters) { - return false; - } - const returnType = getReturnTypeOfSignature(signature); - return isFunctionType(returnType) || isConstructorType(returnType); + function isGenericFunctionReturningFunction(signature) { + return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature))); } function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) { return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) || !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & 1048576 /* Union */) && !(getReducedType(apparentFuncType).flags & 131072 /* Never */) && isTypeAssignableTo(funcType, globalFunctionType); diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 7790762703763..b629c7681e98a 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -54,7 +54,7 @@ var path = __toESM(require("path")); // src/compiler/corePublic.ts var versionMajorMinor = "5.4"; -var version = "5.4.2"; +var version = "5.4.3"; // src/compiler/core.ts var emptyArray = []; diff --git a/package-lock.json b/package-lock.json index 83d8d02918663..0f3b38bbadadb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript", - "version": "5.4.2", + "version": "5.4.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript", - "version": "5.4.2", + "version": "5.4.3", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 565e35da2e438..f6b9ceca6dc33 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "https://www.typescriptlang.org/", - "version": "5.4.2", + "version": "5.4.3", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/src/compiler/corePublic.ts b/src/compiler/corePublic.ts index a1f7376ba0ece..6684032a0969a 100644 --- a/src/compiler/corePublic.ts +++ b/src/compiler/corePublic.ts @@ -4,7 +4,7 @@ export const versionMajorMinor = "5.4"; // The following is baselined as a literal template type without intervention /** The version of the TypeScript compiler release */ // eslint-disable-next-line @typescript-eslint/no-inferrable-types -export const version = "5.4.2" as string; +export const version = "5.4.3" as string; /** * Type of objects whose values are all of the same type. From b45a41823ecaff6c1554a4c69161db10b2eba6ab Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 18 Mar 2024 11:56:40 -0700 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#57801=20(Dist?= =?UTF-8?q?ribute=20mapped=20types=20over=20array/...)=20into=20release-5.?= =?UTF-8?q?4=20(#57832)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anders Hejlsberg --- src/compiler/checker.ts | 53 +++++++++------- .../mappedArrayTupleIntersections.symbols | 62 +++++++++++++++++++ .../mappedArrayTupleIntersections.types | 40 ++++++++++++ .../compiler/mappedArrayTupleIntersections.ts | 21 +++++++ 4 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 tests/baselines/reference/mappedArrayTupleIntersections.symbols create mode 100644 tests/baselines/reference/mappedArrayTupleIntersections.types create mode 100644 tests/cases/compiler/mappedArrayTupleIntersections.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3981ebc1255ff..4abe2f0eec1b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14557,7 +14557,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraint = getConstraintTypeFromMappedType(type); if (constraint.flags & TypeFlags.Index) { const baseConstraint = getBaseConstraintOfType((constraint as IndexType).type); - if (baseConstraint && everyType(baseConstraint, isArrayOrTupleType)) { + if (baseConstraint && everyType(baseConstraint, t => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); } } @@ -14565,6 +14565,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } + function isArrayOrTupleOrIntersection(type: Type) { + return !!(type.flags & TypeFlags.Intersection) && every((type as IntersectionType).types, isArrayOrTupleType); + } + function isMappedTypeGenericIndexedAccess(type: Type) { let objectType; return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped && @@ -19759,6 +19763,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // * If T is a union type we distribute the mapped type over the union. // * If T is an array we map to an array where the element type has been transformed. // * If T is a tuple we map to a tuple where the element types have been transformed. + // * If T is an intersection of array or tuple types we map to an intersection of transformed array or tuple types. // * Otherwise we map to an object type where the type of each property has been transformed. // For example, when T is instantiated to a union type A | B, we produce { [P in keyof A]: X } | // { [P in keyof B]: X }, and when when T is instantiated to a union type A | undefined, we produce @@ -19767,33 +19772,33 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (typeVariable) { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { - return mapTypeWithAlias( - getReducedType(mappedTypeVariable), - t => { - if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) { - if (!type.declaration.nameType) { - let constraint; - if ( - isArrayType(t) || t.flags & TypeFlags.Any && findResolutionCycleStartIndex(typeVariable, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 && - (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType) - ) { - return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); - } - if (isTupleType(t)) { - return instantiateMappedTupleType(t, type, typeVariable, mapper); - } - } - return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); - } - return t; - }, - aliasSymbol, - aliasTypeArguments, - ); + return mapTypeWithAlias(getReducedType(mappedTypeVariable), instantiateConstituent, aliasSymbol, aliasTypeArguments); } } // If the constraint type of the instantiation is the wildcard type, return the wildcard type. return instantiateType(getConstraintTypeFromMappedType(type), mapper) === wildcardType ? wildcardType : instantiateAnonymousType(type, mapper, aliasSymbol, aliasTypeArguments); + + function instantiateConstituent(t: Type): Type { + if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && !isErrorType(t)) { + if (!type.declaration.nameType) { + let constraint; + if ( + isArrayType(t) || t.flags & TypeFlags.Any && findResolutionCycleStartIndex(typeVariable!, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 && + (constraint = getConstraintOfTypeParameter(typeVariable!)) && everyType(constraint, isArrayOrTupleType) + ) { + return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable!, t, mapper)); + } + if (isTupleType(t)) { + return instantiateMappedTupleType(t, type, typeVariable!, mapper); + } + if (isArrayOrTupleOrIntersection(t)) { + return getIntersectionType(map((t as IntersectionType).types, instantiateConstituent)); + } + } + return instantiateAnonymousType(type, prependTypeMapping(typeVariable!, t, mapper)); + } + return t; + } } function getModifiedReadonlyState(state: boolean, modifiers: MappedTypeModifiers) { diff --git a/tests/baselines/reference/mappedArrayTupleIntersections.symbols b/tests/baselines/reference/mappedArrayTupleIntersections.symbols new file mode 100644 index 0000000000000..354bdb031d901 --- /dev/null +++ b/tests/baselines/reference/mappedArrayTupleIntersections.symbols @@ -0,0 +1,62 @@ +//// [tests/cases/compiler/mappedArrayTupleIntersections.ts] //// + +=== mappedArrayTupleIntersections.ts === +type Box = { value: T }; +>Box : Symbol(Box, Decl(mappedArrayTupleIntersections.ts, 0, 0)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 0, 9)) +>value : Symbol(value, Decl(mappedArrayTupleIntersections.ts, 0, 15)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 0, 9)) + +type Boxify = { [K in keyof T]: Box }; +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 1, 12)) +>K : Symbol(K, Decl(mappedArrayTupleIntersections.ts, 1, 20)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 1, 12)) +>Box : Symbol(Box, Decl(mappedArrayTupleIntersections.ts, 0, 0)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 1, 12)) +>K : Symbol(K, Decl(mappedArrayTupleIntersections.ts, 1, 20)) + +type T1 = Boxify; +>T1 : Symbol(T1, Decl(mappedArrayTupleIntersections.ts, 1, 47)) +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) + +type T2 = Boxify<[string, string]>; +>T2 : Symbol(T2, Decl(mappedArrayTupleIntersections.ts, 3, 27)) +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) + +type T3 = Boxify; +>T3 : Symbol(T3, Decl(mappedArrayTupleIntersections.ts, 4, 35)) +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) + +type T4 = Boxify; +>T4 : Symbol(T4, Decl(mappedArrayTupleIntersections.ts, 5, 39)) +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) + +type T5 = Boxify; +>T5 : Symbol(T5, Decl(mappedArrayTupleIntersections.ts, 6, 46)) +>Boxify : Symbol(Boxify, Decl(mappedArrayTupleIntersections.ts, 0, 27)) +>x : Symbol(x, Decl(mappedArrayTupleIntersections.ts, 7, 29)) + +// https://github.com/microsoft/TypeScript/issues/57744 + +type MustBeArray = T; +>MustBeArray : Symbol(MustBeArray, Decl(mappedArrayTupleIntersections.ts, 7, 43)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 11, 17)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 11, 17)) + +type Hmm = T extends number[] ? +>Hmm : Symbol(Hmm, Decl(mappedArrayTupleIntersections.ts, 11, 38)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 13, 9)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 13, 9)) + + MustBeArray<{ [I in keyof T]: 1 }> : +>MustBeArray : Symbol(MustBeArray, Decl(mappedArrayTupleIntersections.ts, 7, 43)) +>I : Symbol(I, Decl(mappedArrayTupleIntersections.ts, 14, 19)) +>T : Symbol(T, Decl(mappedArrayTupleIntersections.ts, 13, 9)) + + never; + +type X = Hmm<[3, 4, 5]>; +>X : Symbol(X, Decl(mappedArrayTupleIntersections.ts, 15, 10)) +>Hmm : Symbol(Hmm, Decl(mappedArrayTupleIntersections.ts, 11, 38)) + diff --git a/tests/baselines/reference/mappedArrayTupleIntersections.types b/tests/baselines/reference/mappedArrayTupleIntersections.types new file mode 100644 index 0000000000000..db4a465853fc9 --- /dev/null +++ b/tests/baselines/reference/mappedArrayTupleIntersections.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/mappedArrayTupleIntersections.ts] //// + +=== mappedArrayTupleIntersections.ts === +type Box = { value: T }; +>Box : Box +>value : T + +type Boxify = { [K in keyof T]: Box }; +>Boxify : Boxify + +type T1 = Boxify; +>T1 : Box[] + +type T2 = Boxify<[string, string]>; +>T2 : [Box, Box] + +type T3 = Boxify; +>T3 : Box[] & Box[] + +type T4 = Boxify; +>T4 : Box[] & [Box, Box] + +type T5 = Boxify; +>T5 : Boxify +>x : string + +// https://github.com/microsoft/TypeScript/issues/57744 + +type MustBeArray = T; +>MustBeArray : T + +type Hmm = T extends number[] ? +>Hmm : Hmm + + MustBeArray<{ [I in keyof T]: 1 }> : + never; + +type X = Hmm<[3, 4, 5]>; +>X : [1, 1, 1] + diff --git a/tests/cases/compiler/mappedArrayTupleIntersections.ts b/tests/cases/compiler/mappedArrayTupleIntersections.ts new file mode 100644 index 0000000000000..4947e71a5d39c --- /dev/null +++ b/tests/cases/compiler/mappedArrayTupleIntersections.ts @@ -0,0 +1,21 @@ +// @strict: true +// @noEmit: true + +type Box = { value: T }; +type Boxify = { [K in keyof T]: Box }; + +type T1 = Boxify; +type T2 = Boxify<[string, string]>; +type T3 = Boxify; +type T4 = Boxify; +type T5 = Boxify; + +// https://github.com/microsoft/TypeScript/issues/57744 + +type MustBeArray = T; + +type Hmm = T extends number[] ? + MustBeArray<{ [I in keyof T]: 1 }> : + never; + +type X = Hmm<[3, 4, 5]>; From fc7006c125914a2d7146027744500ef8a308c5f6 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 18 Mar 2024 20:41:16 +0000 Subject: [PATCH 06/10] Update LKG --- lib/tsc.js | 44 +++++++++++++++++++++++--------------------- lib/tsserver.js | 44 +++++++++++++++++++++++--------------------- lib/typescript.js | 44 +++++++++++++++++++++++--------------------- 3 files changed, 69 insertions(+), 63 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index f3f3150c5d65b..3eb234d2d3789 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -55321,13 +55321,16 @@ function createTypeChecker(host) { const constraint = getConstraintTypeFromMappedType(type); if (constraint.flags & 4194304 /* Index */) { const baseConstraint = getBaseConstraintOfType(constraint.type); - if (baseConstraint && everyType(baseConstraint, isArrayOrTupleType)) { + if (baseConstraint && everyType(baseConstraint, (t) => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); } } } return type; } + function isArrayOrTupleOrIntersection(type) { + return !!(type.flags & 2097152 /* Intersection */) && every(type.types, isArrayOrTupleType); + } function isMappedTypeGenericIndexedAccess(type) { let objectType; return !!(type.flags & 8388608 /* IndexedAccess */ && getObjectFlags(objectType = type.objectType) & 32 /* Mapped */ && !isGenericMappedType(objectType) && isGenericIndexType(type.indexType) && !(getMappedTypeModifiers(objectType) & 8 /* ExcludeOptional */) && !objectType.declaration.nameType); @@ -59698,29 +59701,28 @@ function createTypeChecker(host) { if (typeVariable) { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { - return mapTypeWithAlias( - getReducedType(mappedTypeVariable), - (t) => { - if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { - if (!type.declaration.nameType) { - let constraint; - if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { - return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); - } - if (isTupleType(t)) { - return instantiateMappedTupleType(t, type, typeVariable, mapper); - } - } - return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); - } - return t; - }, - aliasSymbol, - aliasTypeArguments - ); + return mapTypeWithAlias(getReducedType(mappedTypeVariable), instantiateConstituent, aliasSymbol, aliasTypeArguments); } } return instantiateType(getConstraintTypeFromMappedType(type), mapper) === wildcardType ? wildcardType : instantiateAnonymousType(type, mapper, aliasSymbol, aliasTypeArguments); + function instantiateConstituent(t) { + if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { + if (!type.declaration.nameType) { + let constraint; + if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { + return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); + } + if (isTupleType(t)) { + return instantiateMappedTupleType(t, type, typeVariable, mapper); + } + if (isArrayOrTupleOrIntersection(t)) { + return getIntersectionType(map(t.types, instantiateConstituent)); + } + } + return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); + } + return t; + } } function getModifiedReadonlyState(state, modifiers) { return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state; diff --git a/lib/tsserver.js b/lib/tsserver.js index df1f3dd752ab6..0ddc801d51c86 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -60065,13 +60065,16 @@ function createTypeChecker(host) { const constraint = getConstraintTypeFromMappedType(type); if (constraint.flags & 4194304 /* Index */) { const baseConstraint = getBaseConstraintOfType(constraint.type); - if (baseConstraint && everyType(baseConstraint, isArrayOrTupleType)) { + if (baseConstraint && everyType(baseConstraint, (t) => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); } } } return type; } + function isArrayOrTupleOrIntersection(type) { + return !!(type.flags & 2097152 /* Intersection */) && every(type.types, isArrayOrTupleType); + } function isMappedTypeGenericIndexedAccess(type) { let objectType; return !!(type.flags & 8388608 /* IndexedAccess */ && getObjectFlags(objectType = type.objectType) & 32 /* Mapped */ && !isGenericMappedType(objectType) && isGenericIndexType(type.indexType) && !(getMappedTypeModifiers(objectType) & 8 /* ExcludeOptional */) && !objectType.declaration.nameType); @@ -64442,29 +64445,28 @@ function createTypeChecker(host) { if (typeVariable) { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { - return mapTypeWithAlias( - getReducedType(mappedTypeVariable), - (t) => { - if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { - if (!type.declaration.nameType) { - let constraint; - if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { - return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); - } - if (isTupleType(t)) { - return instantiateMappedTupleType(t, type, typeVariable, mapper); - } - } - return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); - } - return t; - }, - aliasSymbol, - aliasTypeArguments - ); + return mapTypeWithAlias(getReducedType(mappedTypeVariable), instantiateConstituent, aliasSymbol, aliasTypeArguments); } } return instantiateType(getConstraintTypeFromMappedType(type), mapper) === wildcardType ? wildcardType : instantiateAnonymousType(type, mapper, aliasSymbol, aliasTypeArguments); + function instantiateConstituent(t) { + if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { + if (!type.declaration.nameType) { + let constraint; + if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { + return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); + } + if (isTupleType(t)) { + return instantiateMappedTupleType(t, type, typeVariable, mapper); + } + if (isArrayOrTupleOrIntersection(t)) { + return getIntersectionType(map(t.types, instantiateConstituent)); + } + } + return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); + } + return t; + } } function getModifiedReadonlyState(state, modifiers) { return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state; diff --git a/lib/typescript.js b/lib/typescript.js index 05672d241e67b..8b56699181efc 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -57820,13 +57820,16 @@ ${lanes.join("\n")} const constraint = getConstraintTypeFromMappedType(type); if (constraint.flags & 4194304 /* Index */) { const baseConstraint = getBaseConstraintOfType(constraint.type); - if (baseConstraint && everyType(baseConstraint, isArrayOrTupleType)) { + if (baseConstraint && everyType(baseConstraint, (t) => isArrayOrTupleType(t) || isArrayOrTupleOrIntersection(t))) { return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper)); } } } return type; } + function isArrayOrTupleOrIntersection(type) { + return !!(type.flags & 2097152 /* Intersection */) && every(type.types, isArrayOrTupleType); + } function isMappedTypeGenericIndexedAccess(type) { let objectType; return !!(type.flags & 8388608 /* IndexedAccess */ && getObjectFlags(objectType = type.objectType) & 32 /* Mapped */ && !isGenericMappedType(objectType) && isGenericIndexType(type.indexType) && !(getMappedTypeModifiers(objectType) & 8 /* ExcludeOptional */) && !objectType.declaration.nameType); @@ -62197,29 +62200,28 @@ ${lanes.join("\n")} if (typeVariable) { const mappedTypeVariable = instantiateType(typeVariable, mapper); if (typeVariable !== mappedTypeVariable) { - return mapTypeWithAlias( - getReducedType(mappedTypeVariable), - (t) => { - if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { - if (!type.declaration.nameType) { - let constraint; - if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { - return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); - } - if (isTupleType(t)) { - return instantiateMappedTupleType(t, type, typeVariable, mapper); - } - } - return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); - } - return t; - }, - aliasSymbol, - aliasTypeArguments - ); + return mapTypeWithAlias(getReducedType(mappedTypeVariable), instantiateConstituent, aliasSymbol, aliasTypeArguments); } } return instantiateType(getConstraintTypeFromMappedType(type), mapper) === wildcardType ? wildcardType : instantiateAnonymousType(type, mapper, aliasSymbol, aliasTypeArguments); + function instantiateConstituent(t) { + if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && !isErrorType(t)) { + if (!type.declaration.nameType) { + let constraint; + if (isArrayType(t) || t.flags & 1 /* Any */ && findResolutionCycleStartIndex(typeVariable, 4 /* ImmediateBaseConstraint */) < 0 && (constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) { + return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper)); + } + if (isTupleType(t)) { + return instantiateMappedTupleType(t, type, typeVariable, mapper); + } + if (isArrayOrTupleOrIntersection(t)) { + return getIntersectionType(map(t.types, instantiateConstituent)); + } + } + return instantiateAnonymousType(type, prependTypeMapping(typeVariable, t, mapper)); + } + return t; + } } function getModifiedReadonlyState(state, modifiers) { return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state; From 010b1885c089189425a0f7d34bd02305401f8928 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:54:29 -0700 Subject: [PATCH 07/10] release-5.4: Revert PR 56087 (#57850) --- src/compiler/checker.ts | 6 ---- .../declarationEmitUsingTypeAlias1.errors.txt | 34 +++++++++++++++++++ .../declarationEmitUsingTypeAlias1.js | 6 ---- 3 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitUsingTypeAlias1.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4abe2f0eec1b9..71dc5a4e83c67 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5735,12 +5735,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Checks if two symbols, through aliasing and/or merging, refer to the same thing */ function getSymbolIfSameReference(s1: Symbol, s2: Symbol) { - if (s1.flags & SymbolFlags.TypeAlias && s2.declarations?.find(isTypeAlias)) { - s2 = getDeclaredTypeOfTypeAlias(s2).aliasSymbol || s2; - } - if (s2.flags & SymbolFlags.TypeAlias && s1.declarations?.find(isTypeAlias)) { - s1 = getDeclaredTypeOfTypeAlias(s1).aliasSymbol || s1; - } if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) { return s1; } diff --git a/tests/baselines/reference/declarationEmitUsingTypeAlias1.errors.txt b/tests/baselines/reference/declarationEmitUsingTypeAlias1.errors.txt new file mode 100644 index 0000000000000..c31e66a237a62 --- /dev/null +++ b/tests/baselines/reference/declarationEmitUsingTypeAlias1.errors.txt @@ -0,0 +1,34 @@ +src/index.ts(3,14): error TS2742: The inferred type of 'foo' cannot be named without a reference to '../node_modules/some-dep/dist/inner'. This is likely not portable. A type annotation is necessary. +src/index.ts(7,14): error TS2742: The inferred type of 'bar' cannot be named without a reference to '../node_modules/some-dep/dist/inner'. This is likely not portable. A type annotation is necessary. + + +==== node_modules/some-dep/dist/inner.d.ts (0 errors) ==== + export declare type Other = { other: string }; + export declare type SomeType = { arg: Other }; + +==== node_modules/some-dep/dist/index.d.ts (0 errors) ==== + export type OtherType = import('./inner').Other; + export type SomeType = import('./inner').SomeType; + +==== node_modules/some-dep/package.json (0 errors) ==== + { + "name": "some-dep", + "exports": { + ".": "./dist/index.js" + } + } + +==== src/index.ts (2 errors) ==== + import { SomeType } from "some-dep"; + + export const foo = (thing: SomeType) => { + ~~~ +!!! error TS2742: The inferred type of 'foo' cannot be named without a reference to '../node_modules/some-dep/dist/inner'. This is likely not portable. A type annotation is necessary. + return thing; + }; + + export const bar = (thing: SomeType) => { + ~~~ +!!! error TS2742: The inferred type of 'bar' cannot be named without a reference to '../node_modules/some-dep/dist/inner'. This is likely not portable. A type annotation is necessary. + return thing.arg; + }; \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitUsingTypeAlias1.js b/tests/baselines/reference/declarationEmitUsingTypeAlias1.js index 9bfe2999627b9..541c8c65140c9 100644 --- a/tests/baselines/reference/declarationEmitUsingTypeAlias1.js +++ b/tests/baselines/reference/declarationEmitUsingTypeAlias1.js @@ -39,9 +39,3 @@ var bar = function (thing) { return thing.arg; }; exports.bar = bar; - - -//// [index.d.ts] -import { SomeType } from "some-dep"; -export declare const foo: (thing: SomeType) => import("some-dep").SomeType; -export declare const bar: (thing: SomeType) => import("some-dep").OtherType; From ca8e720a36618eb1323f8dbc36a45a8fd5b35d78 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 19 Mar 2024 20:56:37 +0000 Subject: [PATCH 08/10] Update LKG --- lib/tsc.js | 7 ------- lib/tsserver.js | 7 ------- lib/typescript.js | 7 ------- 3 files changed, 21 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index 3eb234d2d3789..f1b0030a23869 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -47517,13 +47517,6 @@ function createTypeChecker(host) { }); } function getSymbolIfSameReference(s1, s2) { - var _a, _b; - if (s1.flags & 524288 /* TypeAlias */ && ((_a = s2.declarations) == null ? void 0 : _a.find(isTypeAlias))) { - s2 = getDeclaredTypeOfTypeAlias(s2).aliasSymbol || s2; - } - if (s2.flags & 524288 /* TypeAlias */ && ((_b = s1.declarations) == null ? void 0 : _b.find(isTypeAlias))) { - s1 = getDeclaredTypeOfTypeAlias(s1).aliasSymbol || s1; - } if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) { return s1; } diff --git a/lib/tsserver.js b/lib/tsserver.js index 0ddc801d51c86..04602f13318f4 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -52261,13 +52261,6 @@ function createTypeChecker(host) { }); } function getSymbolIfSameReference(s1, s2) { - var _a, _b; - if (s1.flags & 524288 /* TypeAlias */ && ((_a = s2.declarations) == null ? void 0 : _a.find(isTypeAlias))) { - s2 = getDeclaredTypeOfTypeAlias(s2).aliasSymbol || s2; - } - if (s2.flags & 524288 /* TypeAlias */ && ((_b = s1.declarations) == null ? void 0 : _b.find(isTypeAlias))) { - s1 = getDeclaredTypeOfTypeAlias(s1).aliasSymbol || s1; - } if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) { return s1; } diff --git a/lib/typescript.js b/lib/typescript.js index 8b56699181efc..65799b4b0bac8 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -50016,13 +50016,6 @@ ${lanes.join("\n")} }); } function getSymbolIfSameReference(s1, s2) { - var _a, _b; - if (s1.flags & 524288 /* TypeAlias */ && ((_a = s2.declarations) == null ? void 0 : _a.find(isTypeAlias))) { - s2 = getDeclaredTypeOfTypeAlias(s2).aliasSymbol || s2; - } - if (s2.flags & 524288 /* TypeAlias */ && ((_b = s1.declarations) == null ? void 0 : _b.find(isTypeAlias))) { - s1 = getDeclaredTypeOfTypeAlias(s1).aliasSymbol || s1; - } if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) { return s1; } From cd06f92c43eede05731cc0592bcb4ee7fe4d38cc Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 19 Mar 2024 15:07:36 -0700 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#57853=20(Reve?= =?UTF-8?q?rt=20PR=2056161)=20into=20release-5.4=20(#57854)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> --- src/compiler/checker.ts | 2 +- .../reference/enumWithInfinityProperty.errors.txt | 10 ---------- .../baselines/reference/enumWithNaNProperty.errors.txt | 10 ---------- .../enumWithNegativeInfinityProperty.errors.txt | 10 ---------- 4 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 tests/baselines/reference/enumWithInfinityProperty.errors.txt delete mode 100644 tests/baselines/reference/enumWithNaNProperty.errors.txt delete mode 100644 tests/baselines/reference/enumWithNegativeInfinityProperty.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71dc5a4e83c67..3fef78b1df9fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -45377,7 +45377,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } else { const text = getTextOfPropertyName(member.name); - if (isNumericLiteralName(text)) { + if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } diff --git a/tests/baselines/reference/enumWithInfinityProperty.errors.txt b/tests/baselines/reference/enumWithInfinityProperty.errors.txt deleted file mode 100644 index 27de0a69b0383..0000000000000 --- a/tests/baselines/reference/enumWithInfinityProperty.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -enumWithInfinityProperty.ts(2,5): error TS2452: An enum member cannot have a numeric name. - - -==== enumWithInfinityProperty.ts (1 errors) ==== - enum A { - Infinity = 1 - ~~~~~~~~ -!!! error TS2452: An enum member cannot have a numeric name. - } - \ No newline at end of file diff --git a/tests/baselines/reference/enumWithNaNProperty.errors.txt b/tests/baselines/reference/enumWithNaNProperty.errors.txt deleted file mode 100644 index 941fa099eefe2..0000000000000 --- a/tests/baselines/reference/enumWithNaNProperty.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -enumWithNaNProperty.ts(2,5): error TS2452: An enum member cannot have a numeric name. - - -==== enumWithNaNProperty.ts (1 errors) ==== - enum A { - NaN = 1 - ~~~ -!!! error TS2452: An enum member cannot have a numeric name. - } - \ No newline at end of file diff --git a/tests/baselines/reference/enumWithNegativeInfinityProperty.errors.txt b/tests/baselines/reference/enumWithNegativeInfinityProperty.errors.txt deleted file mode 100644 index d9923989b8a3f..0000000000000 --- a/tests/baselines/reference/enumWithNegativeInfinityProperty.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -enumWithNegativeInfinityProperty.ts(2,5): error TS2452: An enum member cannot have a numeric name. - - -==== enumWithNegativeInfinityProperty.ts (1 errors) ==== - enum A { - "-Infinity" = 1 - ~~~~~~~~~~~ -!!! error TS2452: An enum member cannot have a numeric name. - } - \ No newline at end of file From 6ea273cdcca99db809074d2b2d38d0e5b59ee81b Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 19 Mar 2024 22:08:46 +0000 Subject: [PATCH 10/10] Update LKG --- lib/tsc.js | 2 +- lib/tsserver.js | 2 +- lib/typescript.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tsc.js b/lib/tsc.js index f1b0030a23869..e6dcc303eb9c7 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -80672,7 +80672,7 @@ function createTypeChecker(host) { error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { const text = getTextOfPropertyName(member.name); - if (isNumericLiteralName(text)) { + if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } diff --git a/lib/tsserver.js b/lib/tsserver.js index 04602f13318f4..bc0e83fb4070a 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -85416,7 +85416,7 @@ function createTypeChecker(host) { error2(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { const text = getTextOfPropertyName(member.name); - if (isNumericLiteralName(text)) { + if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error2(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } diff --git a/lib/typescript.js b/lib/typescript.js index 65799b4b0bac8..7014c9a443241 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -83171,7 +83171,7 @@ ${lanes.join("\n")} error2(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { const text = getTextOfPropertyName(member.name); - if (isNumericLiteralName(text)) { + if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error2(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy