diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ce2d09f9d0e53..1bcdab3dd945d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4461,8 +4461,8 @@ namespace ts { kind === SyntaxKind.SetAccessor ? factory.createSetAccessorDeclaration(/*decorators*/ undefined, options?.modifiers, options?.name ?? factory.createIdentifier(""), parameters, /*body*/ undefined) : kind === SyntaxKind.IndexSignature ? factory.createIndexSignature(/*decorators*/ undefined, options?.modifiers, parameters, returnTypeNode) : kind === SyntaxKind.JSDocFunctionType ? factory.createJSDocFunctionType(parameters, returnTypeNode) : - kind === SyntaxKind.FunctionType ? factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(typeParameters, parameters, returnTypeNode) : + kind === SyntaxKind.FunctionType ? factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : + kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : kind === SyntaxKind.FunctionDeclaration ? factory.createFunctionDeclaration(/*decorators*/ undefined, options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : kind === SyntaxKind.FunctionExpression ? factory.createFunctionExpression(options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, factory.createBlock([])) : kind === SyntaxKind.ArrowFunction ? factory.createArrowFunction(options?.modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, factory.createBlock([])) : @@ -6075,7 +6075,7 @@ namespace ts { visitNode(p.type, visitExistingNodeTreeSymbols), /*initializer*/ undefined )), - visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) + visitNode(newTypeNode ?? node.type, visitExistingNodeTreeSymbols) ?? factory.createTypeReferenceNode(factory.createIdentifier("")) ); } else { @@ -6090,7 +6090,7 @@ namespace ts { visitNode(p.type, visitExistingNodeTreeSymbols), /*initializer*/ undefined )), - visitNode(node.type, visitExistingNodeTreeSymbols) + visitNode(node.type, visitExistingNodeTreeSymbols) ?? factory.createTypeReferenceNode(factory.createIdentifier("")) ); } } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 1d67d380d2c60..6bc234c56ea82 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -4772,7 +4772,7 @@ namespace ts { return array ? createNodeArray(array) : undefined; } - function asName(name: string | T): T | Identifier { + function asName(name: string | T): T | Identifier { return typeof name === "string" ? createIdentifier(name) : name; } @@ -4946,9 +4946,9 @@ namespace ts { case SyntaxKind.JSDocFunctionType: return factory.createJSDocFunctionType(parameters, type); case SyntaxKind.FunctionType: - return factory.createFunctionTypeNode(typeParameters, parameters, type); + return factory.createFunctionTypeNode(typeParameters, parameters, Debug.assertDefined(type)); case SyntaxKind.ConstructorType: - return factory.createConstructorTypeNode(typeParameters, parameters, type); + return factory.createConstructorTypeNode(typeParameters, parameters, Debug.assertDefined(type)); case SyntaxKind.FunctionDeclaration: return factory.createFunctionDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, typeParameters, parameters, type, /*body*/ undefined); case SyntaxKind.FunctionExpression: @@ -5514,8 +5514,8 @@ namespace ts { (node: Mutable) => { node.transformFlags |= transformFlags; }; } - function observeArguments(action: (arg1: U, arg2: U) => U, observer: ((arg1: T, arg2: T) => void) | undefined): (arg1: U, arg2: U) => U; - function observeArguments(action: (arg1: T, arg2: U | undefined) => R, observer: ((arg1: T, arg2: U) => void) | undefined): (arg1: T, arg2: U | undefined) => R; + function observeArguments(arg1: U, arg2: U) => U>(action: F, observer: ((arg1: T, arg2: T) => void) | undefined): F; + function observeArguments R>(action: F, observer: ((arg1: T, arg2: U) => void) | undefined): F; function observeArguments(action: (arg1: T, arg2: U) => R, observer: ((arg1: T, arg2: U) => void) | undefined): (arg1: T, arg2: U) => R { return !observer ? action : (arg1, arg2) => { if (arg2 !== undefined) { @@ -5525,8 +5525,8 @@ namespace ts { }; } - function observeResult(action: (arg: U) => U, observer: ((result: T) => void) | undefined): (arg: U) => U; - function observeResult(action: (arg: T) => R, observer: ((result: R) => void) | undefined): (arg: T) => R; + function observeResult(arg: U) => U>(action: F, observer: ((result: T) => void) | undefined): F; + function observeResult R>(action: F, observer: ((result: R) => void) | undefined): F; function observeResult(action: (arg: T) => R, observer: ((result: R) => void) | undefined): (arg: T) => R { return !observer ? action : arg => { const result = action(arg); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a301ad1d7c3f3..64f7937ecf19a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2670,6 +2670,8 @@ namespace ts { ); } + function parseReturnType(returnToken: SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode; + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined; function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean) { if (shouldParseReturnType(returnToken, isType)) { return parseTypeOrTypePredicate(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2acfed01bc3b9..a483cf686fe17 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3991,7 +3991,7 @@ namespace ts { WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) UseOnlyExternalAliasing = 1 << 7, // Only use external aliases for a symbol - SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. + SuppressAnyReturnType = 1 << 8, // If the return type is any-like and can be elided, don't offer a return type. WriteTypeParametersInQualifiedName = 1 << 9, MultilineObjectLiterals = 1 << 10, // Always write object literals across multiple lines WriteClassExpressionAsTypeLiteral = 1 << 11, // Write class {} as { new(): {} } - used for mixin declaration emit @@ -6398,10 +6398,10 @@ namespace ts { updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; - createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode; - updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; - createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode; - updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; createTypeQueryNode(exprName: EntityName): TypeQueryNode; updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index c55a0d0f4b42c..3d4c02bd1ec51 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -110,7 +110,9 @@ namespace ts.codefix { } function transformJSDocFunctionType(node: JSDocFunctionType) { - return factory.createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type); + // TODO: This does not properly handle `function(new:C, string)` per https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System#the-javascript-type-language + // however we do handle it correctly in `serializeTypeForDeclaration` in checker.ts + return factory.createFunctionTypeNode(emptyArray, node.parameters.map(transformJSDocParameter), node.type ?? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)); } function transformJSDocParameter(node: ParameterDeclaration) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 24a620f9b48c2..c5facc69bc3c2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3043,10 +3043,10 @@ declare namespace ts { updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; - createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode; - updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; - createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode; - updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; createTypeQueryNode(exprName: EntityName): TypeQueryNode; updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; @@ -9584,19 +9584,19 @@ declare namespace ts { /** * @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ - createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => FunctionTypeNode, + createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => FunctionTypeNode, /** * @deprecated Use `factory.updateFunctionTypeNode` or the factory supplied by your transformation context instead. */ - updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => FunctionTypeNode, + updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => FunctionTypeNode, /** * @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ - createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => ConstructorTypeNode, + createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => ConstructorTypeNode, /** * @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ - updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => ConstructorTypeNode, + updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode, /** * @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 46c1f7ecf5567..7421245817480 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3043,10 +3043,10 @@ declare namespace ts { updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; createTypeReferenceNode(typeName: string | EntityName, typeArguments?: readonly TypeNode[]): TypeReferenceNode; updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; - createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode; - updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; - createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode; - updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructorTypeNode; + createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; + updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; createTypeQueryNode(exprName: EntityName): TypeQueryNode; updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; @@ -6127,19 +6127,19 @@ declare namespace ts { /** * @deprecated Use `factory.createFunctionTypeNode` or the factory supplied by your transformation context instead. */ - createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => FunctionTypeNode, + createFunctionTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => FunctionTypeNode, /** * @deprecated Use `factory.updateFunctionTypeNode` or the factory supplied by your transformation context instead. */ - updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => FunctionTypeNode, + updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => FunctionTypeNode, /** * @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ - createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined) => ConstructorTypeNode, + createConstructorTypeNode: (typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode) => ConstructorTypeNode, /** * @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ - updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) => ConstructorTypeNode, + updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode, /** * @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */