Skip to content

Commit af3e1d4

Browse files
authored
Reuse type nodes from optional parameters even when not written as a union with undefined (microsoft#48605)
* Reuse type nodes from optional parameters and properties even when not written as a union with `undefined` * Remove newly unneeded NodeBuilderFlag * Update public API * Update baselines from main
1 parent 12c4ea8 commit af3e1d4

File tree

51 files changed

+246
-113
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+246
-113
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5915,9 +5915,6 @@ namespace ts {
59155915
if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) {
59165916
parameterType = getOptionalType(parameterType);
59175917
}
5918-
if ((context.flags & NodeBuilderFlags.NoUndefinedOptionalParameterType) && parameterDeclaration && !isJSDocParameterTag(parameterDeclaration) && isOptionalUninitializedParameter(parameterDeclaration)) {
5919-
parameterType = getTypeWithFacts(parameterType, TypeFacts.NEUndefined);
5920-
}
59215918
const parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports);
59225919

59235920
const modifiers = !(context.flags & NodeBuilderFlags.OmitParameterModifiers) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(factory.cloneNode) : undefined;
@@ -6544,7 +6541,7 @@ namespace ts {
65446541
if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation) && !isGetAccessorDeclaration(declWithExistingAnnotation)) {
65456542
// try to reuse the existing annotation
65466543
const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
6547-
if (getTypeFromTypeNode(existing) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
6544+
if (typeNodeIsEquivalentToType(existing, declWithExistingAnnotation, type) && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
65486545
const result = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled);
65496546
if (result) {
65506547
return result;
@@ -6562,6 +6559,17 @@ namespace ts {
65626559
return result;
65636560
}
65646561

6562+
function typeNodeIsEquivalentToType(typeNode: TypeNode, annotatedDeclaration: Declaration, type: Type) {
6563+
const typeFromTypeNode = getTypeFromTypeNode(typeNode);
6564+
if (typeFromTypeNode === type) {
6565+
return true;
6566+
}
6567+
if (isParameter(annotatedDeclaration) && annotatedDeclaration.questionToken) {
6568+
return getTypeWithFacts(type, TypeFacts.NEUndefined) === typeFromTypeNode;
6569+
}
6570+
return false;
6571+
}
6572+
65656573
function serializeReturnTypeForSignature(context: NodeBuilderContext, type: Type, signature: Signature, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) {
65666574
if (!isErrorType(type) && context.enclosingDeclaration) {
65676575
const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration);
@@ -42579,12 +42587,6 @@ namespace ts {
4257942587
hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier);
4258042588
}
4258142589

42582-
function isOptionalUninitializedParameter(parameter: ParameterDeclaration) {
42583-
return !!strictNullChecks &&
42584-
isOptionalParameter(parameter) &&
42585-
!parameter.initializer;
42586-
}
42587-
4258842590
function isExpandoFunctionDeclaration(node: Declaration): boolean {
4258942591
const declaration = getParseTreeNode(node, isFunctionDeclaration);
4259042592
if (!declaration) {

src/compiler/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4490,7 +4490,6 @@ namespace ts {
44904490
UseAliasDefinedOutsideCurrentScope = 1 << 14, // Allow non-visible aliases
44914491
UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type
44924492
NoTypeReduction = 1 << 29, // Don't call getReducedType
4493-
NoUndefinedOptionalParameterType = 1 << 30, // Do not add undefined to optional parameter type
44944493

44954494
// Error handling
44964495
AllowThisInObjectLiteral = 1 << 15,

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7654,4 +7654,8 @@ namespace ts {
76547654

76557655
return state > States.NodeModules ? { topLevelNodeModulesIndex, topLevelPackageNameIndex, packageRootIndex, fileNameIndex } : undefined;
76567656
}
7657+
7658+
export function getParameterTypeNode(parameter: ParameterDeclaration | JSDocParameterTag) {
7659+
return parameter.kind === SyntaxKind.JSDocParameterTag ? parameter.typeExpression?.type : parameter.type;
7660+
}
76577661
}

src/services/codefixes/helpers.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ namespace ts.codefix {
194194
const scriptTarget = getEmitScriptTarget(program.getCompilerOptions());
195195
const flags =
196196
NodeBuilderFlags.NoTruncation
197-
| NodeBuilderFlags.NoUndefinedOptionalParameterType
198197
| NodeBuilderFlags.SuppressAnyReturnType
199198
| NodeBuilderFlags.AllowEmptyTuple
200199
| (quotePreference === QuotePreference.Single ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : NodeBuilderFlags.None);

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,6 @@ declare namespace ts {
23942394
UseAliasDefinedOutsideCurrentScope = 16384,
23952395
UseSingleQuotesForStringLiteralType = 268435456,
23962396
NoTypeReduction = 536870912,
2397-
NoUndefinedOptionalParameterType = 1073741824,
23982397
AllowThisInObjectLiteral = 32768,
23992398
AllowQualifiedNameInPlaceOfIdentifier = 65536,
24002399
/** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */

tests/baselines/reference/api/typescript.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,6 @@ declare namespace ts {
23942394
UseAliasDefinedOutsideCurrentScope = 16384,
23952395
UseSingleQuotesForStringLiteralType = 268435456,
23962396
NoTypeReduction = 536870912,
2397-
NoUndefinedOptionalParameterType = 1073741824,
23982397
AllowThisInObjectLiteral = 32768,
23992398
AllowQualifiedNameInPlaceOfIdentifier = 65536,
24002399
/** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */

tests/baselines/reference/arrayFakeFlatNoCrashInferenceDeclarations.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type BadFlatArray<Arr, Depth extends number> = {obj: {
1919
>1 : 1
2020

2121
declare function flat<A, D extends number = 1>(
22-
>flat : <A, D extends number = 1>(arr: A, depth?: D | undefined) => BadFlatArray<A, D>[]
22+
>flat : <A, D extends number = 1>(arr: A, depth?: D) => BadFlatArray<A, D>[]
2323

2424
arr: A,
2525
>arr : A

tests/baselines/reference/assertionTypePredicates1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ namespace Debug {
270270
>Debug : typeof Debug
271271

272272
export declare function assert(value: unknown, message?: string): asserts value;
273-
>assert : (value: unknown, message?: string | undefined) => asserts value
273+
>assert : (value: unknown, message?: string) => asserts value
274274
>value : unknown
275275
>message : string | undefined
276276

tests/baselines/reference/asyncFunctionsAndStrictNullChecks.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ declare function resolve2<T>(value: T): Windows.Foundation.IPromise<T>;
7575
>Foundation : any
7676

7777
async function sample2(x?: number) {
78-
>sample2 : (x?: number | undefined) => Promise<void>
78+
>sample2 : (x?: number) => Promise<void>
7979
>x : number | undefined
8080

8181
let x1 = await resolve1(x);

tests/baselines/reference/callsOnComplexSignatures.types

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function test3(items: string[] | number[]) {
110110
}
111111

112112
function test4(
113-
>test4 : (arg1: ((...objs: { x: number;}[]) => number) | ((...objs: { y: number;}[]) => number), arg2: ((a: { x: number;}, b: object) => number) | ((a: object, b: { x: number;}) => number), arg3: ((a: { x: number;}, ...objs: { y: number;}[]) => number) | ((...objs: { x: number;}[]) => number), arg4: ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number), arg5: ((a?: { x: number; } | undefined, ...b: { x: number;}[]) => number) | ((a?: { y: number; } | undefined) => number), arg6: ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number;}[]) => number)) => void
113+
>test4 : (arg1: ((...objs: { x: number;}[]) => number) | ((...objs: { y: number;}[]) => number), arg2: ((a: { x: number;}, b: object) => number) | ((a: object, b: { x: number;}) => number), arg3: ((a: { x: number;}, ...objs: { y: number;}[]) => number) | ((...objs: { x: number;}[]) => number), arg4: ((a?: { x: number;}, b?: { x: number;}) => number) | ((a?: { y: number;}) => number), arg5: ((a?: { x: number;}, ...b: { x: number;}[]) => number) | ((a?: { y: number;}) => number), arg6: ((a?: { x: number;}, b?: { x: number;}) => number) | ((...a: { y: number;}[]) => number)) => void
114114

115115
arg1: ((...objs: {x: number}[]) => number) | ((...objs: {y: number}[]) => number),
116116
>arg1 : ((...objs: { x: number;}[]) => number) | ((...objs: { y: number;}[]) => number)
@@ -138,7 +138,7 @@ function test4(
138138
>x : number
139139

140140
arg4: ((a?: {x: number}, b?: {x: number}) => number) | ((a?: {y: number}) => number),
141-
>arg4 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((a?: { y: number; } | undefined) => number)
141+
>arg4 : ((a?: { x: number;}, b?: { x: number;}) => number) | ((a?: { y: number;}) => number)
142142
>a : { x: number; } | undefined
143143
>x : number
144144
>b : { x: number; } | undefined
@@ -147,7 +147,7 @@ function test4(
147147
>y : number
148148

149149
arg5: ((a?: {x: number}, ...b: {x: number}[]) => number) | ((a?: {y: number}) => number),
150-
>arg5 : ((a?: { x: number; } | undefined, ...b: { x: number;}[]) => number) | ((a?: { y: number; } | undefined) => number)
150+
>arg5 : ((a?: { x: number;}, ...b: { x: number;}[]) => number) | ((a?: { y: number;}) => number)
151151
>a : { x: number; } | undefined
152152
>x : number
153153
>b : { x: number; }[]
@@ -156,7 +156,7 @@ function test4(
156156
>y : number
157157

158158
arg6: ((a?: {x: number}, b?: {x: number}) => number) | ((...a: {y: number}[]) => number),
159-
>arg6 : ((a?: { x: number; } | undefined, b?: { x: number; } | undefined) => number) | ((...a: { y: number;}[]) => number)
159+
>arg6 : ((a?: { x: number;}, b?: { x: number;}) => number) | ((...a: { y: number;}[]) => number)
160160
>a : { x: number; } | undefined
161161
>x : number
162162
>b : { x: number; } | undefined
@@ -339,7 +339,7 @@ function test5() {
339339

340340
// Pair of non-like intrinsics
341341
function render(url?: string): React.ReactNode {
342-
>render : (url?: string | undefined) => React.ReactNode
342+
>render : (url?: string) => React.ReactNode
343343
>url : string | undefined
344344
>React : any
345345

0 commit comments

Comments
 (0)