Comments (1)
The problem is that @type
can be a source of an effective return type node for an arrow function like this. I don't know all the rules but it's kinda like a mix of a contextual type and an explicit return type annotation. And an explicit return type annotation has to refer to Promise
.
A quick experiment to ignore @type
tags for this purpose here shows that it's not really a good idea:
git diff
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index d0a2843989..13407fdb86 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -39900,7 +39900,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function checkSignatureDeclarationDiagnostics() {
checkCollisionWithArgumentsInGeneratedCode(node);
- let returnTypeNode = getEffectiveReturnTypeNode(node);
+ let returnTypeNode = getEffectiveReturnTypeNode(node, /*ignoreTypeTag*/ true);
let returnTypeErrorLocation = returnTypeNode;
if (isInJSFile(node)) {
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 018eda7cb1..5ad67a9cd6 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -6657,10 +6657,10 @@ export function getTypeAnnotationNode(node: Node): TypeNode | undefined {
*
* @internal
*/
-export function getEffectiveReturnTypeNode(node: SignatureDeclaration | JSDocSignature): TypeNode | undefined {
+export function getEffectiveReturnTypeNode(node: SignatureDeclaration | JSDocSignature, ignoreTypeTag = false): TypeNode | undefined {
return isJSDocSignature(node) ?
node.type && node.type.typeExpression && node.type.typeExpression.type :
- node.type || (isInJSFile(node) ? getJSDocReturnType(node) : undefined);
+ node.type || (isInJSFile(node) ? getJSDocReturnType(node, ignoreTypeTag) : undefined);
}
/** @internal */
diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts
index 60e19b0e47..b8370acca9 100644
--- a/src/compiler/utilitiesPublic.ts
+++ b/src/compiler/utilitiesPublic.ts
@@ -1182,11 +1182,14 @@ export function getJSDocType(node: Node): TypeNode | undefined {
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
* gets the type from inside the braces, after the fat arrow, etc.
*/
-export function getJSDocReturnType(node: Node): TypeNode | undefined {
+export function getJSDocReturnType(node: Node, ignoreTypeTag = false): TypeNode | undefined {
const returnTag = getJSDocReturnTag(node);
if (returnTag && returnTag.typeExpression) {
return returnTag.typeExpression.type;
}
+ if (ignoreTypeTag) {
+ return;
+ }
const typeTag = getJSDocTypeTag(node);
if (typeTag && typeTag.typeExpression) {
const type = typeTag.typeExpression.type;
diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts
index ad1b05ed05..aa5623451e 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -8577,7 +8577,7 @@ declare namespace ts {
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
* gets the type from inside the braces, after the fat arrow, etc.
*/
- function getJSDocReturnType(node: Node): TypeNode | undefined;
+ function getJSDocReturnType(node: Node, ignoreTypeTag?: boolean): TypeNode | undefined;
/** Get all JSDoc tags related to a node, including those on parent nodes. */
function getJSDocTags(node: Node): readonly JSDocTag[];
/** Gets all JSDoc tags that match a specified predicate */
diff --git a/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt b/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt
index 417262fef3..36b0ddea7b 100644
--- a/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt
+++ b/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt
@@ -1,13 +1,11 @@
file.js(3,17): error TS2322: Type 'number' is not assignable to type 'string'.
-file.js(6,24): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'?
file.js(7,23): error TS2322: Type 'number' is not assignable to type 'string'.
-file.js(10,24): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'?
file.js(12,2): error TS2322: Type 'number' is not assignable to type 'string'.
-file.js(19,3): error TS2345: Argument of type '() => Promise<number>' is not assignable to parameter of type '() => string'.
+file.js(24,3): error TS2345: Argument of type '() => Promise<number>' is not assignable to parameter of type '() => string'.
Type 'Promise<number>' is not assignable to type 'string'.
-==== file.js (6 errors) ====
+==== file.js (4 errors) ====
// Error (good)
/** @type {function(): string} */
const a = () => 0
@@ -16,22 +14,23 @@ file.js(19,3): error TS2345: Argument of type '() => Promise<number>' is not ass
// Error (good)
/** @type {function(): string} */
- ~~~~~~
-!!! error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'?
const b = async () => 0
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
// No error (bad)
/** @type {function(): string} */
- ~~~~~~
-!!! error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'?
const c = async () => {
return 0
~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
+ /** @type {function(): string} */
+ const d = async () => {
+ return ""
+ }
+
/** @type {function(function(): string): void} */
const f = (p) => {}
diff --git a/tests/baselines/reference/asyncArrowFunction_allowJs.symbols b/tests/baselines/reference/asyncArrowFunction_allowJs.symbols
index 6cb66a2b9e..8ee40f15df 100644
--- a/tests/baselines/reference/asyncArrowFunction_allowJs.symbols
+++ b/tests/baselines/reference/asyncArrowFunction_allowJs.symbols
@@ -19,14 +19,21 @@ const c = async () => {
return 0
}
+/** @type {function(): string} */
+const d = async () => {
+>d : Symbol(d, Decl(file.js, 15, 5))
+
+ return ""
+}
+
/** @type {function(function(): string): void} */
const f = (p) => {}
->f : Symbol(f, Decl(file.js, 15, 5))
->p : Symbol(p, Decl(file.js, 15, 11))
+>f : Symbol(f, Decl(file.js, 20, 5))
+>p : Symbol(p, Decl(file.js, 20, 11))
// Error (good)
f(async () => {
->f : Symbol(f, Decl(file.js, 15, 5))
+>f : Symbol(f, Decl(file.js, 20, 5))
return 0
})
diff --git a/tests/baselines/reference/asyncArrowFunction_allowJs.types b/tests/baselines/reference/asyncArrowFunction_allowJs.types
index ecf9f7d9cc..068136f341 100644
--- a/tests/baselines/reference/asyncArrowFunction_allowJs.types
+++ b/tests/baselines/reference/asyncArrowFunction_allowJs.types
@@ -34,6 +34,18 @@ const c = async () => {
> : ^
}
+/** @type {function(): string} */
+const d = async () => {
+>d : () => string
+> : ^^^^^^^^^^^^
+>async () => { return ""} : () => string
+> : ^^^^^^^^^^^^
+
+ return ""
+>"" : ""
+> : ^^
+}
+
/** @type {function(function(): string): void} */
const f = (p) => {}
>f : (arg0: () => string) => void
diff --git a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts
index 9c21ae8557..7e490966d1 100644
--- a/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts
+++ b/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts
@@ -18,6 +18,11 @@ const c = async () => {
return 0
}
+/** @type {function(): string} */
+const d = async () => {
+ return ""
+}
+
/** @type {function(function(): string): void} */
const f = (p) => {}
Some of the errors in asyncArrowFunction_allowJs
became confusing (they don't mention Promise
at all now). There is also no error reported for the d
function that I added there which is super bad.
from typescript.
Related Issues (20)
- Modify the issue templates `bug_report.yml` and `feature_request.yml` to improve the quality of further submitted issues HOT 6
- Duplicate diagnostics HOT 2
- `const enum` references in the body of nodes with grammar errors are not inlined
- `static` methods can access `this.constructor` without complaints and compiles correctly, but a runtime error shows up HOT 13
- ModuleResolution Node16/NodeNext fails without extension starting on 5.5.0-dev.20240413 HOT 8
- Type predicate covariant comparison is unsound HOT 1
- Assignability to `asserts` type predicate is not checked HOT 1
- Constrained type param with `keyof` seems to have inconsistent behavior HOT 2
- Why generics are not working as expected? HOT 3
- Type guarding against BigInt using typeof not working - but using instanceof works, even though that javascript code will not work HOT 1
- Type check and Object key completion on overloaded functions with generic types defined in a class are incorrect
- Computed Void is an Expected Param where Void is not HOT 4
- Narrowing empty string or false in generic misbehaves HOT 2
- `tsc` compile `proposal-explicit-resource-management` different from `babel` and `swc` HOT 1
- After enabling noUncheckedIndexedAccess, using ++ on a default undefined does not trigger an error message. HOT 3
- C++-style `const` modifier on class members HOT 2
- Package Import is not working from neither way "CommonJS" or "Module" HOT 4
- Type guard for child not transitive parent object HOT 3
- Error when compiled JavaScript initializes static properties in a class with a hard private method (`#`) that references a static property
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript.