mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Allow implicit undefined returns when the contextual union type contains it (#57912)
This commit is contained in:
committed by
GitHub
parent
2b2d6cebcb
commit
f6f4eab587
@@ -39125,7 +39125,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (types.length === 0) {
|
||||
// For an async function, the return type will not be void/undefined, but rather a Promise for void/undefined.
|
||||
const contextualReturnType = getContextualReturnType(func, /*contextFlags*/ undefined);
|
||||
const returnType = contextualReturnType && (unwrapReturnType(contextualReturnType, functionFlags) || voidType).flags & TypeFlags.Undefined ? undefinedType : voidType;
|
||||
const returnType = contextualReturnType && someType(unwrapReturnType(contextualReturnType, functionFlags) || voidType, t => !!(t.flags & TypeFlags.Undefined)) ? undefinedType : voidType;
|
||||
return functionFlags & FunctionFlags.Async ? createPromiseReturnType(func, returnType) : // Async function
|
||||
returnType; // Normal function
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(5,17): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
|
||||
functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(9,17): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
|
||||
functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(17,7): error TS2322: Type '() => void' is not assignable to type '() => number | undefined'.
|
||||
Type 'void' is not assignable to type 'number | undefined'.
|
||||
functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(21,7): error TS2322: Type '() => void' is not assignable to type '() => number'.
|
||||
Type 'void' is not assignable to type 'number'.
|
||||
functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(29,23): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
|
||||
@@ -10,7 +8,7 @@ functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(52,3): error T
|
||||
Type 'void' is not assignable to type 'undefined'.
|
||||
|
||||
|
||||
==== functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts (7 errors) ====
|
||||
==== functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts (6 errors) ====
|
||||
function f10(): undefined {
|
||||
// Ok, return type allows implicit return of undefined
|
||||
}
|
||||
@@ -32,10 +30,7 @@ functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(52,3): error T
|
||||
}
|
||||
|
||||
const f21: () => undefined | number = () => {
|
||||
~~~
|
||||
!!! error TS2322: Type '() => void' is not assignable to type '() => number | undefined'.
|
||||
!!! error TS2322: Type 'void' is not assignable to type 'number | undefined'.
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
}
|
||||
|
||||
const f22: () => number = () => {
|
||||
@@ -85,4 +80,20 @@ functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts(52,3): error T
|
||||
}
|
||||
|
||||
f(h2);
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57840
|
||||
|
||||
type FN = () => Promise<undefined> | undefined;
|
||||
|
||||
const fn1: FN = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn2: FN = async () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn3: FN = () => {};
|
||||
|
||||
const fn4: FN = async () => {};
|
||||
|
||||
@@ -18,7 +18,7 @@ const f20: () => undefined = () => {
|
||||
}
|
||||
|
||||
const f21: () => undefined | number = () => {
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
}
|
||||
|
||||
const f22: () => number = () => {
|
||||
@@ -58,6 +58,22 @@ function h2(): undefined {
|
||||
}
|
||||
|
||||
f(h2);
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57840
|
||||
|
||||
type FN = () => Promise<undefined> | undefined;
|
||||
|
||||
const fn1: FN = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn2: FN = async () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn3: FN = () => {};
|
||||
|
||||
const fn4: FN = async () => {};
|
||||
|
||||
|
||||
//// [functionsMissingReturnStatementsAndExpressionsStrictNullChecks.js]
|
||||
@@ -74,7 +90,7 @@ const f20 = () => {
|
||||
// Ok, contextual type for implicit return is undefined
|
||||
};
|
||||
const f21 = () => {
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
};
|
||||
const f22 = () => {
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
@@ -98,3 +114,11 @@ f(h1); // Error
|
||||
function h2() {
|
||||
}
|
||||
f(h2);
|
||||
const fn1 = () => {
|
||||
return;
|
||||
};
|
||||
const fn2 = async () => {
|
||||
return;
|
||||
};
|
||||
const fn3 = () => { };
|
||||
const fn4 = async () => { };
|
||||
|
||||
@@ -28,7 +28,7 @@ const f20: () => undefined = () => {
|
||||
const f21: () => undefined | number = () => {
|
||||
>f21 : Symbol(f21, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 16, 5))
|
||||
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
}
|
||||
|
||||
const f22: () => number = () => {
|
||||
@@ -92,3 +92,31 @@ f(h2);
|
||||
>f : Symbol(f, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 34, 1))
|
||||
>h2 : Symbol(h2, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 51, 6))
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57840
|
||||
|
||||
type FN = () => Promise<undefined> | undefined;
|
||||
>FN : Symbol(FN, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 56, 6))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
|
||||
const fn1: FN = () => {
|
||||
>fn1 : Symbol(fn1, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 62, 5))
|
||||
>FN : Symbol(FN, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 56, 6))
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const fn2: FN = async () => {
|
||||
>fn2 : Symbol(fn2, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 66, 5))
|
||||
>FN : Symbol(FN, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 56, 6))
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const fn3: FN = () => {};
|
||||
>fn3 : Symbol(fn3, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 70, 5))
|
||||
>FN : Symbol(FN, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 56, 6))
|
||||
|
||||
const fn4: FN = async () => {};
|
||||
>fn4 : Symbol(fn4, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 72, 5))
|
||||
>FN : Symbol(FN, Decl(functionsMissingReturnStatementsAndExpressionsStrictNullChecks.ts, 56, 6))
|
||||
|
||||
|
||||
@@ -34,10 +34,10 @@ const f20: () => undefined = () => {
|
||||
const f21: () => undefined | number = () => {
|
||||
>f21 : () => undefined | number
|
||||
> : ^^^^^^
|
||||
>() => { // Error, regular void function because contextual type for implicit return isn't just undefined} : () => void
|
||||
> : ^^^^^^^^^^
|
||||
>() => { // Ok, contextual type for implicit return contains undefined} : () => undefined
|
||||
> : ^^^^^^^^^^^^^^^
|
||||
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
}
|
||||
|
||||
const f22: () => number = () => {
|
||||
@@ -132,3 +132,39 @@ f(h2);
|
||||
>h2 : () => undefined
|
||||
> : ^^^^^^
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57840
|
||||
|
||||
type FN = () => Promise<undefined> | undefined;
|
||||
>FN : FN
|
||||
> : ^^
|
||||
|
||||
const fn1: FN = () => {
|
||||
>fn1 : FN
|
||||
> : ^^
|
||||
>() => { return;} : () => undefined
|
||||
> : ^^^^^^^^^^^^^^^
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const fn2: FN = async () => {
|
||||
>fn2 : FN
|
||||
> : ^^
|
||||
>async () => { return;} : () => Promise<undefined>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const fn3: FN = () => {};
|
||||
>fn3 : FN
|
||||
> : ^^
|
||||
>() => {} : () => undefined
|
||||
> : ^^^^^^^^^^^^^^^
|
||||
|
||||
const fn4: FN = async () => {};
|
||||
>fn4 : FN
|
||||
> : ^^
|
||||
>async () => {} : () => Promise<undefined>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -46,16 +46,16 @@ function flatMapChildren<T>(node: Node, cb: (child: Node) => readonly T[] | T |
|
||||
> : ^^^^^^^
|
||||
|
||||
node.forEachChild(child => {
|
||||
>node.forEachChild(child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } }) : void | undefined
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>node.forEachChild(child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } }) : undefined
|
||||
> : ^^^^^^^^^
|
||||
>node.forEachChild : <T_1>(cbNode: (node: Node) => T_1 | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T_1 | undefined) => T_1 | undefined
|
||||
> : ^^^^^^ ^^ ^^ ^^^ ^^^^^
|
||||
>node : Node
|
||||
> : ^^^^
|
||||
>forEachChild : <T_1>(cbNode: (node: Node) => T_1 | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T_1 | undefined) => T_1 | undefined
|
||||
> : ^^^^^^ ^^ ^^ ^^^ ^^^^^
|
||||
>child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } } : (child: Node) => void
|
||||
> : ^ ^^^^^^^^^^^^^^^
|
||||
>child => { const value = cb(child); if (value !== undefined) { result.push(...toArray(value)); } } : (child: Node) => undefined
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^^
|
||||
>child : Node
|
||||
> : ^^^^
|
||||
|
||||
@@ -118,16 +118,16 @@ function flatMapChildren2<T>(node: Node, cb: (child: Node) => readonly T[] | T |
|
||||
> : ^^^^^^^
|
||||
|
||||
node.forEachChild(child => {
|
||||
>node.forEachChild(child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } }) : void | undefined
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>node.forEachChild(child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } }) : undefined
|
||||
> : ^^^^^^^^^
|
||||
>node.forEachChild : <T_1>(cbNode: (node: Node) => T_1 | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T_1 | undefined) => T_1 | undefined
|
||||
> : ^^^^^^ ^^ ^^ ^^^ ^^^^^
|
||||
>node : Node
|
||||
> : ^^^^
|
||||
>forEachChild : <T_1>(cbNode: (node: Node) => T_1 | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T_1 | undefined) => T_1 | undefined
|
||||
> : ^^^^^^ ^^ ^^ ^^^ ^^^^^
|
||||
>child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } } : (child: Node) => void
|
||||
> : ^ ^^^^^^^^^^^^^^^
|
||||
>child => { const value = cb(child); if (value !== null) { result.push(...toArray(value)); } } : (child: Node) => undefined
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^^
|
||||
>child : Node
|
||||
> : ^^^^
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ const f20: () => undefined = () => {
|
||||
}
|
||||
|
||||
const f21: () => undefined | number = () => {
|
||||
// Error, regular void function because contextual type for implicit return isn't just undefined
|
||||
// Ok, contextual type for implicit return contains undefined
|
||||
}
|
||||
|
||||
const f22: () => number = () => {
|
||||
@@ -59,3 +59,19 @@ function h2(): undefined {
|
||||
}
|
||||
|
||||
f(h2);
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57840
|
||||
|
||||
type FN = () => Promise<undefined> | undefined;
|
||||
|
||||
const fn1: FN = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn2: FN = async () => {
|
||||
return;
|
||||
};
|
||||
|
||||
const fn3: FN = () => {};
|
||||
|
||||
const fn4: FN = async () => {};
|
||||
|
||||
Reference in New Issue
Block a user