mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 11:54:44 -06:00
Merge pull request #8767 from Microsoft/neverTypeInference
Only infer 'never' in function expressions and arrow functions
This commit is contained in:
commit
74e2154a51
@ -11586,7 +11586,7 @@ namespace ts {
|
||||
let types: Type[];
|
||||
const funcIsGenerator = !!func.asteriskToken;
|
||||
if (funcIsGenerator) {
|
||||
types = checkAndAggregateYieldOperandTypes(<Block>func.body, contextualMapper);
|
||||
types = checkAndAggregateYieldOperandTypes(func, contextualMapper);
|
||||
if (types.length === 0) {
|
||||
const iterableIteratorAny = createIterableIteratorType(anyType);
|
||||
if (compilerOptions.noImplicitAny) {
|
||||
@ -11597,8 +11597,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const hasImplicitReturn = !!(func.flags & NodeFlags.HasImplicitReturn);
|
||||
types = checkAndAggregateReturnExpressionTypes(<Block>func.body, contextualMapper, isAsync, hasImplicitReturn);
|
||||
types = checkAndAggregateReturnExpressionTypes(func, contextualMapper);
|
||||
if (!types) {
|
||||
return neverType;
|
||||
}
|
||||
@ -11656,10 +11655,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkAndAggregateYieldOperandTypes(body: Block, contextualMapper?: TypeMapper): Type[] {
|
||||
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] {
|
||||
const aggregatedTypes: Type[] = [];
|
||||
|
||||
forEachYieldExpression(body, yieldExpression => {
|
||||
forEachYieldExpression(<Block>func.body, yieldExpression => {
|
||||
const expr = yieldExpression.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
@ -11678,10 +11677,12 @@ namespace ts {
|
||||
return aggregatedTypes;
|
||||
}
|
||||
|
||||
function checkAndAggregateReturnExpressionTypes(body: Block, contextualMapper: TypeMapper, isAsync: boolean, hasImplicitReturn: boolean): Type[] {
|
||||
function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] {
|
||||
const isAsync = isAsyncFunctionLike(func);
|
||||
const aggregatedTypes: Type[] = [];
|
||||
let hasOmittedExpressions = false;
|
||||
forEachReturnStatement(body, returnStatement => {
|
||||
let hasReturnWithNoExpression = !!(func.flags & NodeFlags.HasImplicitReturn);
|
||||
let hasReturnOfTypeNever = false;
|
||||
forEachReturnStatement(<Block>func.body, returnStatement => {
|
||||
const expr = returnStatement.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
@ -11690,20 +11691,24 @@ namespace ts {
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body should be unwrapped to its awaited type, which should be wrapped in
|
||||
// the native Promise<T> type by the caller.
|
||||
type = checkAwaitedType(type, body.parent, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
|
||||
type = checkAwaitedType(type, func, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
|
||||
}
|
||||
if (type !== neverType && !contains(aggregatedTypes, type)) {
|
||||
if (type === neverType) {
|
||||
hasReturnOfTypeNever = true;
|
||||
}
|
||||
else if (!contains(aggregatedTypes, type)) {
|
||||
aggregatedTypes.push(type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
hasOmittedExpressions = true;
|
||||
hasReturnWithNoExpression = true;
|
||||
}
|
||||
});
|
||||
if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) {
|
||||
if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever ||
|
||||
func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction)) {
|
||||
return undefined;
|
||||
}
|
||||
if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) {
|
||||
if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) {
|
||||
if (!contains(aggregatedTypes, undefinedType)) {
|
||||
aggregatedTypes.push(undefinedType);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ let cond: boolean;
|
||||
>cond : boolean
|
||||
|
||||
function ff() {
|
||||
>ff : () => never
|
||||
>ff : () => void
|
||||
|
||||
let x: string | undefined;
|
||||
>x : string | undefined
|
||||
|
||||
@ -7,7 +7,7 @@ while (true) {
|
||||
>true : boolean
|
||||
|
||||
function f() {
|
||||
>f : () => never
|
||||
>f : () => void
|
||||
|
||||
target:
|
||||
>target : any
|
||||
|
||||
@ -16,7 +16,7 @@ for (var x = <number>undefined; ;) { }
|
||||
|
||||
// new declaration space, making redeclaring x as a string valid
|
||||
function declSpace() {
|
||||
>declSpace : () => never
|
||||
>declSpace : () => void
|
||||
|
||||
for (var x = 'this is a string'; ;) { }
|
||||
>x : string
|
||||
|
||||
@ -42,7 +42,7 @@ function isB(x: any): x is B {
|
||||
}
|
||||
|
||||
function f1(x: A | B) {
|
||||
>f1 : (x: A | B) => never
|
||||
>f1 : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
@ -78,7 +78,7 @@ function f1(x: A | B) {
|
||||
}
|
||||
|
||||
function f2(x: A | B) {
|
||||
>f2 : (x: A | B) => never
|
||||
>f2 : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings3.ts ===
|
||||
function a0() {
|
||||
>a0 : () => never
|
||||
>a0 : () => void
|
||||
{
|
||||
for (let x = 0; x < 1; ) {
|
||||
>x : number
|
||||
@ -26,7 +26,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => never
|
||||
>a1 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -48,7 +48,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => never
|
||||
>a2 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings4.ts ===
|
||||
function a0() {
|
||||
>a0 : () => never
|
||||
>a0 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -28,7 +28,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => never
|
||||
>a1 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -60,7 +60,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => never
|
||||
>a2 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -93,7 +93,7 @@ function a2() {
|
||||
|
||||
|
||||
function a3() {
|
||||
>a3 : () => never
|
||||
>a3 : () => void
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings6.ts ===
|
||||
function a0() {
|
||||
>a0 : () => never
|
||||
>a0 : () => void
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -27,7 +27,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => never
|
||||
>a1 : () => void
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -58,7 +58,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => never
|
||||
>a2 : () => void
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -89,7 +89,7 @@ function a2() {
|
||||
}
|
||||
|
||||
function a3() {
|
||||
>a3 : () => never
|
||||
>a3 : () => void
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
//// [neverType.ts]
|
||||
|
||||
function error(message: string) {
|
||||
|
||||
function error(message: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function errorVoid(message: string) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
@ -8,7 +13,19 @@ function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function infiniteLoop1() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function infiniteLoop2(): never {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
@ -33,6 +50,21 @@ function check<T>(x: T | undefined) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
|
||||
class C {
|
||||
void1() {
|
||||
throw new Error();
|
||||
}
|
||||
void2() {
|
||||
while (true) {}
|
||||
}
|
||||
never1(): never {
|
||||
throw new Error();
|
||||
}
|
||||
never2(): never {
|
||||
while (true) {}
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
@ -47,13 +79,6 @@ function f2(x: string | number) {
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
let s = cb();
|
||||
return s;
|
||||
@ -71,10 +96,23 @@ test(errorCallback);
|
||||
function error(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
function errorVoid(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
function infiniteLoop() {
|
||||
function failOrThrow(shouldFail) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
function infiniteLoop1() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
function infiniteLoop2() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
@ -95,6 +133,23 @@ function move2(direction) {
|
||||
function check(x) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.void1 = function () {
|
||||
throw new Error();
|
||||
};
|
||||
C.prototype.void2 = function () {
|
||||
while (true) { }
|
||||
};
|
||||
C.prototype.never1 = function () {
|
||||
throw new Error();
|
||||
};
|
||||
C.prototype.never2 = function () {
|
||||
while (true) { }
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
function f1(x) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
@ -107,12 +162,6 @@ function f2(x) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function failOrThrow(shouldFail) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
function test(cb) {
|
||||
var s = cb();
|
||||
return s;
|
||||
@ -126,13 +175,21 @@ test(errorCallback);
|
||||
|
||||
//// [neverType.d.ts]
|
||||
declare function error(message: string): never;
|
||||
declare function errorVoid(message: string): void;
|
||||
declare function fail(): never;
|
||||
declare function infiniteLoop(): never;
|
||||
declare function failOrThrow(shouldFail: boolean): never;
|
||||
declare function infiniteLoop1(): void;
|
||||
declare function infiniteLoop2(): never;
|
||||
declare function move1(direction: "up" | "down"): number;
|
||||
declare function move2(direction: "up" | "down"): number;
|
||||
declare function check<T>(x: T | undefined): T;
|
||||
declare class C {
|
||||
void1(): void;
|
||||
void2(): void;
|
||||
never1(): never;
|
||||
never2(): never;
|
||||
}
|
||||
declare function f1(x: string | number): void;
|
||||
declare function f2(x: string | number): never;
|
||||
declare function failOrThrow(shouldFail: boolean): never;
|
||||
declare function test(cb: () => string): string;
|
||||
declare let errorCallback: () => never;
|
||||
|
||||
@ -1,34 +1,65 @@
|
||||
=== tests/cases/conformance/types/never/neverType.ts ===
|
||||
|
||||
function error(message: string) {
|
||||
|
||||
function error(message: string): never {
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
>message : Symbol(message, Decl(neverType.ts, 1, 15))
|
||||
>message : Symbol(message, Decl(neverType.ts, 2, 15))
|
||||
|
||||
throw new Error(message);
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>message : Symbol(message, Decl(neverType.ts, 1, 15))
|
||||
>message : Symbol(message, Decl(neverType.ts, 2, 15))
|
||||
}
|
||||
|
||||
function errorVoid(message: string) {
|
||||
>errorVoid : Symbol(errorVoid, Decl(neverType.ts, 4, 1))
|
||||
>message : Symbol(message, Decl(neverType.ts, 6, 19))
|
||||
|
||||
throw new Error(message);
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>message : Symbol(message, Decl(neverType.ts, 6, 19))
|
||||
}
|
||||
|
||||
function fail() {
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 8, 1))
|
||||
|
||||
return error("Something failed");
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
>infiniteLoop : Symbol(infiniteLoop, Decl(neverType.ts, 7, 1))
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
>failOrThrow : Symbol(failOrThrow, Decl(neverType.ts, 12, 1))
|
||||
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 14, 21))
|
||||
|
||||
if (shouldFail) {
|
||||
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 14, 21))
|
||||
|
||||
return fail();
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 8, 1))
|
||||
}
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function infiniteLoop1() {
|
||||
>infiniteLoop1 : Symbol(infiniteLoop1, Decl(neverType.ts, 19, 1))
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function infiniteLoop2(): never {
|
||||
>infiniteLoop2 : Symbol(infiniteLoop2, Decl(neverType.ts, 24, 1))
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function move1(direction: "up" | "down") {
|
||||
>move1 : Symbol(move1, Decl(neverType.ts, 12, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
|
||||
>move1 : Symbol(move1, Decl(neverType.ts, 29, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 31, 15))
|
||||
|
||||
switch (direction) {
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 31, 15))
|
||||
|
||||
case "up":
|
||||
return 1;
|
||||
@ -40,98 +71,111 @@ function move1(direction: "up" | "down") {
|
||||
}
|
||||
|
||||
function move2(direction: "up" | "down") {
|
||||
>move2 : Symbol(move2, Decl(neverType.ts, 22, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
|
||||
>move2 : Symbol(move2, Decl(neverType.ts, 39, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 41, 15))
|
||||
|
||||
return direction === "up" ? 1 :
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 41, 15))
|
||||
|
||||
direction === "down" ? -1 :
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 41, 15))
|
||||
|
||||
error("Should never get here");
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
function check<T>(x: T | undefined) {
|
||||
>check : Symbol(check, Decl(neverType.ts, 28, 1))
|
||||
>T : Symbol(T, Decl(neverType.ts, 30, 15))
|
||||
>x : Symbol(x, Decl(neverType.ts, 30, 18))
|
||||
>T : Symbol(T, Decl(neverType.ts, 30, 15))
|
||||
>check : Symbol(check, Decl(neverType.ts, 45, 1))
|
||||
>T : Symbol(T, Decl(neverType.ts, 47, 15))
|
||||
>x : Symbol(x, Decl(neverType.ts, 47, 18))
|
||||
>T : Symbol(T, Decl(neverType.ts, 47, 15))
|
||||
|
||||
return x || error("Undefined value");
|
||||
>x : Symbol(x, Decl(neverType.ts, 30, 18))
|
||||
>x : Symbol(x, Decl(neverType.ts, 47, 18))
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(neverType.ts, 49, 1))
|
||||
|
||||
void1() {
|
||||
>void1 : Symbol(C.void1, Decl(neverType.ts, 51, 9))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
}
|
||||
void2() {
|
||||
>void2 : Symbol(C.void2, Decl(neverType.ts, 54, 5))
|
||||
|
||||
while (true) {}
|
||||
}
|
||||
never1(): never {
|
||||
>never1 : Symbol(C.never1, Decl(neverType.ts, 57, 5))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
}
|
||||
never2(): never {
|
||||
>never2 : Symbol(C.never2, Decl(neverType.ts, 60, 5))
|
||||
|
||||
while (true) {}
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
>f1 : Symbol(f1, Decl(neverType.ts, 32, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
>f1 : Symbol(f1, Decl(neverType.ts, 64, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 66, 12))
|
||||
|
||||
if (typeof x === "boolean") {
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
>x : Symbol(x, Decl(neverType.ts, 66, 12))
|
||||
|
||||
x; // never
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
>x : Symbol(x, Decl(neverType.ts, 66, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: string | number) {
|
||||
>f2 : Symbol(f2, Decl(neverType.ts, 38, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 12))
|
||||
>f2 : Symbol(f2, Decl(neverType.ts, 70, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 72, 12))
|
||||
|
||||
while (true) {
|
||||
if (typeof x === "boolean") {
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 12))
|
||||
>x : Symbol(x, Decl(neverType.ts, 72, 12))
|
||||
|
||||
return x; // never
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 12))
|
||||
>x : Symbol(x, Decl(neverType.ts, 72, 12))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
>failOrThrow : Symbol(failOrThrow, Decl(neverType.ts, 46, 1))
|
||||
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 48, 21))
|
||||
|
||||
if (shouldFail) {
|
||||
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 48, 21))
|
||||
|
||||
return fail();
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
|
||||
}
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>cb : Symbol(cb, Decl(neverType.ts, 55, 14))
|
||||
>test : Symbol(test, Decl(neverType.ts, 78, 1))
|
||||
>cb : Symbol(cb, Decl(neverType.ts, 80, 14))
|
||||
|
||||
let s = cb();
|
||||
>s : Symbol(s, Decl(neverType.ts, 56, 7))
|
||||
>cb : Symbol(cb, Decl(neverType.ts, 55, 14))
|
||||
>s : Symbol(s, Decl(neverType.ts, 81, 7))
|
||||
>cb : Symbol(cb, Decl(neverType.ts, 80, 14))
|
||||
|
||||
return s;
|
||||
>s : Symbol(s, Decl(neverType.ts, 56, 7))
|
||||
>s : Symbol(s, Decl(neverType.ts, 81, 7))
|
||||
}
|
||||
|
||||
let errorCallback = () => error("Error callback");
|
||||
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 60, 3))
|
||||
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 85, 3))
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
|
||||
test(() => "hello");
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>test : Symbol(test, Decl(neverType.ts, 78, 1))
|
||||
|
||||
test(() => fail());
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
|
||||
>test : Symbol(test, Decl(neverType.ts, 78, 1))
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 8, 1))
|
||||
|
||||
test(() => { throw new Error(); })
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>test : Symbol(test, Decl(neverType.ts, 78, 1))
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
test(errorCallback);
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 60, 3))
|
||||
>test : Symbol(test, Decl(neverType.ts, 78, 1))
|
||||
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 85, 3))
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
=== tests/cases/conformance/types/never/neverType.ts ===
|
||||
|
||||
function error(message: string) {
|
||||
|
||||
function error(message: string): never {
|
||||
>error : (message: string) => never
|
||||
>message : string
|
||||
|
||||
@ -10,6 +11,16 @@ function error(message: string) {
|
||||
>message : string
|
||||
}
|
||||
|
||||
function errorVoid(message: string) {
|
||||
>errorVoid : (message: string) => void
|
||||
>message : string
|
||||
|
||||
throw new Error(message);
|
||||
>new Error(message) : Error
|
||||
>Error : ErrorConstructor
|
||||
>message : string
|
||||
}
|
||||
|
||||
function fail() {
|
||||
>fail : () => never
|
||||
|
||||
@ -19,8 +30,32 @@ function fail() {
|
||||
>"Something failed" : string
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
>infiniteLoop : () => never
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
>failOrThrow : (shouldFail: boolean) => never
|
||||
>shouldFail : boolean
|
||||
|
||||
if (shouldFail) {
|
||||
>shouldFail : boolean
|
||||
|
||||
return fail();
|
||||
>fail() : never
|
||||
>fail : () => never
|
||||
}
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
function infiniteLoop1() {
|
||||
>infiniteLoop1 : () => void
|
||||
|
||||
while (true) {
|
||||
>true : boolean
|
||||
}
|
||||
}
|
||||
|
||||
function infiniteLoop2(): never {
|
||||
>infiniteLoop2 : () => never
|
||||
|
||||
while (true) {
|
||||
>true : boolean
|
||||
@ -92,6 +127,37 @@ function check<T>(x: T | undefined) {
|
||||
>"Undefined value" : string
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
void1() {
|
||||
>void1 : () => void
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
void2() {
|
||||
>void2 : () => void
|
||||
|
||||
while (true) {}
|
||||
>true : boolean
|
||||
}
|
||||
never1(): never {
|
||||
>never1 : () => never
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
never2(): never {
|
||||
>never2 : () => never
|
||||
|
||||
while (true) {}
|
||||
>true : boolean
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
>f1 : (x: string | number) => void
|
||||
>x : string | number
|
||||
@ -126,22 +192,6 @@ function f2(x: string | number) {
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
>failOrThrow : (shouldFail: boolean) => never
|
||||
>shouldFail : boolean
|
||||
|
||||
if (shouldFail) {
|
||||
>shouldFail : boolean
|
||||
|
||||
return fail();
|
||||
>fail() : never
|
||||
>fail : () => never
|
||||
}
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
>test : (cb: () => string) => string
|
||||
>cb : () => string
|
||||
|
||||
@ -7,7 +7,7 @@ while (true) {
|
||||
>true : boolean
|
||||
|
||||
function f() {
|
||||
>f : () => never
|
||||
>f : () => void
|
||||
|
||||
target:
|
||||
>target : any
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
=== tests/cases/conformance/statements/throwStatements/throwInEnclosingStatements.ts ===
|
||||
|
||||
function fn(x) {
|
||||
>fn : (x: any) => never
|
||||
>fn : (x: any) => void
|
||||
>x : any
|
||||
|
||||
throw x;
|
||||
@ -78,7 +78,7 @@ class C<T> {
|
||||
>T : T
|
||||
|
||||
biz() {
|
||||
>biz : () => never
|
||||
>biz : () => void
|
||||
|
||||
throw this.value;
|
||||
>this.value : T
|
||||
@ -93,15 +93,15 @@ class C<T> {
|
||||
}
|
||||
|
||||
var aa = {
|
||||
>aa : { id: number; biz(): never; }
|
||||
>{ id:12, biz() { throw this; }} : { id: number; biz(): never; }
|
||||
>aa : { id: number; biz(): void; }
|
||||
>{ id:12, biz() { throw this; }} : { id: number; biz(): void; }
|
||||
|
||||
id:12,
|
||||
>id : number
|
||||
>12 : number
|
||||
|
||||
biz() {
|
||||
>biz : () => never
|
||||
>biz : () => void
|
||||
|
||||
throw this;
|
||||
>this : any
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
function error(message: string) {
|
||||
|
||||
function error(message: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function errorVoid(message: string) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
@ -9,7 +14,19 @@ function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function infiniteLoop1() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function infiniteLoop2(): never {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
@ -34,6 +51,21 @@ function check<T>(x: T | undefined) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
|
||||
class C {
|
||||
void1() {
|
||||
throw new Error();
|
||||
}
|
||||
void2() {
|
||||
while (true) {}
|
||||
}
|
||||
never1(): never {
|
||||
throw new Error();
|
||||
}
|
||||
never2(): never {
|
||||
while (true) {}
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
@ -48,13 +80,6 @@ function f2(x: string | number) {
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
let s = cb();
|
||||
return s;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user