mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
commit
59f269c90a
@ -121,9 +121,9 @@ namespace ts {
|
||||
const nullType = createIntrinsicType(TypeFlags.Null | nullableWideningFlags, "null");
|
||||
const emptyArrayElementType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
|
||||
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
|
||||
const neverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
|
||||
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
const nothingType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
const emptyGenericType = <GenericType><ObjectType>createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
emptyGenericType.instantiations = {};
|
||||
|
||||
@ -2030,12 +2030,7 @@ namespace ts {
|
||||
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, flags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Anonymous) {
|
||||
if (type === nothingType) {
|
||||
writer.writeKeyword("nothing");
|
||||
}
|
||||
else {
|
||||
writeAnonymousType(<ObjectType>type, flags);
|
||||
}
|
||||
writeAnonymousType(<ObjectType>type, flags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
writer.writeStringLiteral(`"${escapeString((<StringLiteralType>type).text)}"`);
|
||||
@ -3676,6 +3671,7 @@ namespace ts {
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return true;
|
||||
case SyntaxKind.ArrayType:
|
||||
@ -5011,7 +5007,7 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
|
||||
if (type.flags & TypeFlags.Null) typeSet.containsNull = true;
|
||||
}
|
||||
else if (type !== nothingType && !contains(typeSet, type)) {
|
||||
else if (type !== neverType && !contains(typeSet, type)) {
|
||||
typeSet.push(type);
|
||||
}
|
||||
}
|
||||
@ -5052,7 +5048,7 @@ namespace ts {
|
||||
// a named type that circularly references itself.
|
||||
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
|
||||
if (types.length === 0) {
|
||||
return nothingType;
|
||||
return neverType;
|
||||
}
|
||||
if (types.length === 1) {
|
||||
return types[0];
|
||||
@ -5072,7 +5068,7 @@ namespace ts {
|
||||
if (typeSet.length === 0) {
|
||||
return typeSet.containsNull ? nullType :
|
||||
typeSet.containsUndefined ? undefinedType :
|
||||
nothingType;
|
||||
neverType;
|
||||
}
|
||||
else if (typeSet.length === 1) {
|
||||
return typeSet[0];
|
||||
@ -5220,6 +5216,8 @@ namespace ts {
|
||||
return undefinedType;
|
||||
case SyntaxKind.NullKeyword:
|
||||
return nullType;
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return neverType;
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return getTypeFromThisTypeNode(node);
|
||||
@ -5865,28 +5863,28 @@ namespace ts {
|
||||
return isIdenticalTo(source, target);
|
||||
}
|
||||
|
||||
if (target.flags & TypeFlags.Any) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Undefined) {
|
||||
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True;
|
||||
}
|
||||
if (source.flags & TypeFlags.Null) {
|
||||
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
||||
}
|
||||
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
|
||||
if (result = enumRelatedTo(source, target, reportErrors)) {
|
||||
return result;
|
||||
if (!(target.flags & TypeFlags.Never)) {
|
||||
if (target.flags & TypeFlags.Any) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Undefined) {
|
||||
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True;
|
||||
}
|
||||
if (source.flags & TypeFlags.Null) {
|
||||
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
||||
}
|
||||
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
|
||||
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
|
||||
if (result = enumRelatedTo(source, target, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (source.flags & (TypeFlags.Any | TypeFlags.Never)) return Ternary.True;
|
||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||
}
|
||||
if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) {
|
||||
return Ternary.True;
|
||||
}
|
||||
}
|
||||
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
|
||||
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (isTypeAny(source)) return Ternary.True;
|
||||
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) {
|
||||
return Ternary.True;
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.FreshObjectLiteral) {
|
||||
@ -7491,7 +7489,7 @@ namespace ts {
|
||||
|
||||
function getTypeWithFacts(type: Type, include: TypeFacts) {
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
return getTypeFacts(type) & include ? type : nothingType;
|
||||
return getTypeFacts(type) & include ? type : neverType;
|
||||
}
|
||||
let firstType: Type;
|
||||
let types: Type[];
|
||||
@ -7508,7 +7506,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : nothingType;
|
||||
return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : neverType;
|
||||
}
|
||||
|
||||
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
|
||||
@ -7629,7 +7627,7 @@ namespace ts {
|
||||
const visitedFlowStart = visitedFlowCount;
|
||||
const result = getTypeAtFlowNode(reference.flowNode);
|
||||
visitedFlowCount = visitedFlowStart;
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === nothingType) {
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === neverType) {
|
||||
return declaredType;
|
||||
}
|
||||
return result;
|
||||
@ -7717,7 +7715,7 @@ namespace ts {
|
||||
|
||||
function getTypeAtFlowCondition(flow: FlowCondition) {
|
||||
let type = getTypeAtFlowNode(flow.antecedent);
|
||||
if (type !== nothingType) {
|
||||
if (type !== neverType) {
|
||||
// If we have an antecedent type (meaning we're reachable in some way), we first
|
||||
// attempt to narrow the antecedent type. If that produces the nothing type, then
|
||||
// we take the type guard as an indication that control could reach here in a
|
||||
@ -7727,7 +7725,7 @@ namespace ts {
|
||||
// narrow that.
|
||||
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
|
||||
type = narrowType(type, flow.expression, assumeTrue);
|
||||
if (type === nothingType) {
|
||||
if (type === neverType) {
|
||||
type = narrowType(declaredType, flow.expression, assumeTrue);
|
||||
}
|
||||
}
|
||||
@ -7949,7 +7947,7 @@ namespace ts {
|
||||
const targetType = type.flags & TypeFlags.TypeParameter ? getApparentType(type) : type;
|
||||
return isTypeAssignableTo(candidate, targetType) ? candidate :
|
||||
isTypeAssignableTo(type, candidate) ? type :
|
||||
nothingType;
|
||||
neverType;
|
||||
}
|
||||
|
||||
function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
@ -11561,6 +11559,9 @@ namespace ts {
|
||||
else {
|
||||
const hasImplicitReturn = !!(func.flags & NodeFlags.HasImplicitReturn);
|
||||
types = checkAndAggregateReturnExpressionTypes(<Block>func.body, contextualMapper, isAsync, hasImplicitReturn);
|
||||
if (!types) {
|
||||
return neverType;
|
||||
}
|
||||
if (types.length === 0) {
|
||||
if (isAsync) {
|
||||
// For an async function, the return type will not be void, but rather a Promise for void.
|
||||
@ -11569,12 +11570,9 @@ namespace ts {
|
||||
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
return promiseType;
|
||||
}
|
||||
else {
|
||||
return voidType;
|
||||
}
|
||||
return voidType;
|
||||
}
|
||||
}
|
||||
// When yield/return statements are contextually typed we allow the return type to be a union type.
|
||||
@ -11654,7 +11652,7 @@ namespace ts {
|
||||
// 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);
|
||||
}
|
||||
if (!contains(aggregatedTypes, type)) {
|
||||
if (type !== neverType && !contains(aggregatedTypes, type)) {
|
||||
aggregatedTypes.push(type);
|
||||
}
|
||||
}
|
||||
@ -11662,6 +11660,9 @@ namespace ts {
|
||||
hasOmittedExpressions = true;
|
||||
}
|
||||
});
|
||||
if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) {
|
||||
return undefined;
|
||||
}
|
||||
if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) {
|
||||
if (!contains(aggregatedTypes, undefinedType)) {
|
||||
aggregatedTypes.push(undefinedType);
|
||||
@ -11697,7 +11698,10 @@ namespace ts {
|
||||
|
||||
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
|
||||
|
||||
if (returnType && !hasExplicitReturn) {
|
||||
if (returnType === neverType) {
|
||||
error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
|
||||
}
|
||||
else if (returnType && !hasExplicitReturn) {
|
||||
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
|
||||
// this function does not conform to the specification.
|
||||
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
|
||||
@ -14761,7 +14765,7 @@ namespace ts {
|
||||
arrayType = getUnionType(filter((arrayOrStringType as UnionType).types, t => !(t.flags & TypeFlags.StringLike)));
|
||||
}
|
||||
else if (arrayOrStringType.flags & TypeFlags.StringLike) {
|
||||
arrayType = nothingType;
|
||||
arrayType = neverType;
|
||||
}
|
||||
const hasStringConstituent = arrayOrStringType !== arrayType;
|
||||
let reportedError = false;
|
||||
@ -14773,7 +14777,7 @@ namespace ts {
|
||||
|
||||
// Now that we've removed all the StringLike types, if no constituents remain, then the entire
|
||||
// arrayOrStringType was a string.
|
||||
if (arrayType === nothingType) {
|
||||
if (arrayType === neverType) {
|
||||
return stringType;
|
||||
}
|
||||
}
|
||||
@ -14834,7 +14838,7 @@ namespace ts {
|
||||
if (func) {
|
||||
const signature = getSignatureFromDeclaration(func);
|
||||
const returnType = getReturnTypeOfSignature(signature);
|
||||
if (strictNullChecks || node.expression) {
|
||||
if (strictNullChecks || node.expression || returnType === neverType) {
|
||||
const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
|
||||
|
||||
if (func.asteriskToken) {
|
||||
|
||||
@ -395,6 +395,7 @@ namespace ts {
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.StringLiteralType:
|
||||
return writeTextOfNode(currentText, type);
|
||||
|
||||
@ -1747,6 +1747,10 @@
|
||||
"category": "Error",
|
||||
"code": 2533
|
||||
},
|
||||
"A function returning 'never' cannot have a reachable end point.": {
|
||||
"category": "Error",
|
||||
"code": 2534
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
|
||||
@ -2368,6 +2368,7 @@ namespace ts {
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
// If these are followed by a dot, then parse these out as a dotted type reference instead.
|
||||
const node = tryParse(parseKeywordAndNoDot);
|
||||
return node || parseTypeReference();
|
||||
@ -2410,6 +2411,7 @@ namespace ts {
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.TypeOfKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.LessThanToken:
|
||||
|
||||
@ -91,6 +91,7 @@ namespace ts {
|
||||
"let": SyntaxKind.LetKeyword,
|
||||
"module": SyntaxKind.ModuleKeyword,
|
||||
"namespace": SyntaxKind.NamespaceKeyword,
|
||||
"never": SyntaxKind.NeverKeyword,
|
||||
"new": SyntaxKind.NewKeyword,
|
||||
"null": SyntaxKind.NullKeyword,
|
||||
"number": SyntaxKind.NumberKeyword,
|
||||
|
||||
@ -164,6 +164,7 @@ namespace ts {
|
||||
IsKeyword,
|
||||
ModuleKeyword,
|
||||
NamespaceKeyword,
|
||||
NeverKeyword,
|
||||
ReadonlyKeyword,
|
||||
RequireKeyword,
|
||||
NumberKeyword,
|
||||
@ -2171,11 +2172,12 @@ namespace ts {
|
||||
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
|
||||
ThisType = 0x02000000, // This type
|
||||
ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
|
||||
Never = 0x08000000, // Never type
|
||||
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
/* @internal */
|
||||
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
|
||||
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null | Never,
|
||||
/* @internal */
|
||||
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
|
||||
StringLike = String | StringLiteral,
|
||||
|
||||
@ -613,6 +613,7 @@ namespace ts {
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return true;
|
||||
case SyntaxKind.VoidKeyword:
|
||||
return node.parent.kind !== SyntaxKind.VoidExpression;
|
||||
|
||||
@ -4,7 +4,7 @@ let cond: boolean;
|
||||
>cond : boolean
|
||||
|
||||
function ff() {
|
||||
>ff : () => void
|
||||
>ff : () => never
|
||||
|
||||
let x: string | undefined;
|
||||
>x : string | undefined
|
||||
|
||||
@ -7,7 +7,7 @@ while (true) {
|
||||
>true : boolean
|
||||
|
||||
function f() {
|
||||
>f : () => void
|
||||
>f : () => never
|
||||
|
||||
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 : () => void
|
||||
>declSpace : () => never
|
||||
|
||||
for (var x = 'this is a string'; ;) { }
|
||||
>x : string
|
||||
|
||||
@ -133,8 +133,8 @@ function fn5(x: Derived1) {
|
||||
// 1.5: y: Derived1
|
||||
// Want: ???
|
||||
let y = x;
|
||||
>y : nothing
|
||||
>x : nothing
|
||||
>y : never
|
||||
>x : never
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ function isB(x: any): x is B {
|
||||
}
|
||||
|
||||
function f1(x: A | B) {
|
||||
>f1 : (x: A | B) => void
|
||||
>f1 : (x: A | B) => never
|
||||
>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) => void
|
||||
>f2 : (x: A | B) => never
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings3.ts ===
|
||||
function a0() {
|
||||
>a0 : () => void
|
||||
>a0 : () => never
|
||||
{
|
||||
for (let x = 0; x < 1; ) {
|
||||
>x : number
|
||||
@ -26,7 +26,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => void
|
||||
>a1 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -48,7 +48,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => void
|
||||
>a2 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings4.ts ===
|
||||
function a0() {
|
||||
>a0 : () => void
|
||||
>a0 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -28,7 +28,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => void
|
||||
>a1 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -60,7 +60,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => void
|
||||
>a2 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
@ -93,7 +93,7 @@ function a2() {
|
||||
|
||||
|
||||
function a3() {
|
||||
>a3 : () => void
|
||||
>a3 : () => never
|
||||
|
||||
for (let x; x < 1;) {
|
||||
>x : any
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/nestedBlockScopedBindings6.ts ===
|
||||
function a0() {
|
||||
>a0 : () => void
|
||||
>a0 : () => never
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -27,7 +27,7 @@ function a0() {
|
||||
}
|
||||
|
||||
function a1() {
|
||||
>a1 : () => void
|
||||
>a1 : () => never
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -58,7 +58,7 @@ function a1() {
|
||||
}
|
||||
|
||||
function a2() {
|
||||
>a2 : () => void
|
||||
>a2 : () => never
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
@ -89,7 +89,7 @@ function a2() {
|
||||
}
|
||||
|
||||
function a3() {
|
||||
>a3 : () => void
|
||||
>a3 : () => never
|
||||
|
||||
for (let x of [1]) {
|
||||
>x : number
|
||||
|
||||
138
tests/baselines/reference/neverType.js
Normal file
138
tests/baselines/reference/neverType.js
Normal file
@ -0,0 +1,138 @@
|
||||
//// [neverType.ts]
|
||||
|
||||
function error(message: string) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function move1(direction: "up" | "down") {
|
||||
switch (direction) {
|
||||
case "up":
|
||||
return 1;
|
||||
case "down":
|
||||
return -1;
|
||||
}
|
||||
return error("Should never get here");
|
||||
}
|
||||
|
||||
function move2(direction: "up" | "down") {
|
||||
return direction === "up" ? 1 :
|
||||
direction === "down" ? -1 :
|
||||
error("Should never get here");
|
||||
}
|
||||
|
||||
function check<T>(x: T | undefined) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: string | number) {
|
||||
while (true) {
|
||||
if (typeof x === "boolean") {
|
||||
return x; // never
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
let s = cb();
|
||||
return s;
|
||||
}
|
||||
|
||||
let errorCallback = () => error("Error callback");
|
||||
|
||||
test(() => "hello");
|
||||
test(() => fail());
|
||||
test(() => { throw new Error(); })
|
||||
test(errorCallback);
|
||||
|
||||
|
||||
//// [neverType.js]
|
||||
function error(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
function infiniteLoop() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
function move1(direction) {
|
||||
switch (direction) {
|
||||
case "up":
|
||||
return 1;
|
||||
case "down":
|
||||
return -1;
|
||||
}
|
||||
return error("Should never get here");
|
||||
}
|
||||
function move2(direction) {
|
||||
return direction === "up" ? 1 :
|
||||
direction === "down" ? -1 :
|
||||
error("Should never get here");
|
||||
}
|
||||
function check(x) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
function f1(x) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
}
|
||||
}
|
||||
function f2(x) {
|
||||
while (true) {
|
||||
if (typeof x === "boolean") {
|
||||
return x; // never
|
||||
}
|
||||
}
|
||||
}
|
||||
function failOrThrow(shouldFail) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
function test(cb) {
|
||||
var s = cb();
|
||||
return s;
|
||||
}
|
||||
var errorCallback = function () { return error("Error callback"); };
|
||||
test(function () { return "hello"; });
|
||||
test(function () { return fail(); });
|
||||
test(function () { throw new Error(); });
|
||||
test(errorCallback);
|
||||
|
||||
|
||||
//// [neverType.d.ts]
|
||||
declare function error(message: string): never;
|
||||
declare function fail(): never;
|
||||
declare function infiniteLoop(): never;
|
||||
declare function move1(direction: "up" | "down"): number;
|
||||
declare function move2(direction: "up" | "down"): number;
|
||||
declare function check<T>(x: T | undefined): T;
|
||||
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;
|
||||
137
tests/baselines/reference/neverType.symbols
Normal file
137
tests/baselines/reference/neverType.symbols
Normal file
@ -0,0 +1,137 @@
|
||||
=== tests/cases/conformance/types/never/neverType.ts ===
|
||||
|
||||
function error(message: string) {
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
>message : Symbol(message, Decl(neverType.ts, 1, 15))
|
||||
|
||||
throw new Error(message);
|
||||
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>message : Symbol(message, Decl(neverType.ts, 1, 15))
|
||||
}
|
||||
|
||||
function fail() {
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
|
||||
|
||||
return error("Something failed");
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
>infiniteLoop : Symbol(infiniteLoop, Decl(neverType.ts, 7, 1))
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function move1(direction: "up" | "down") {
|
||||
>move1 : Symbol(move1, Decl(neverType.ts, 12, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
|
||||
|
||||
switch (direction) {
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
|
||||
|
||||
case "up":
|
||||
return 1;
|
||||
case "down":
|
||||
return -1;
|
||||
}
|
||||
return error("Should never get here");
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
function move2(direction: "up" | "down") {
|
||||
>move2 : Symbol(move2, Decl(neverType.ts, 22, 1))
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
|
||||
|
||||
return direction === "up" ? 1 :
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
|
||||
|
||||
direction === "down" ? -1 :
|
||||
>direction : Symbol(direction, Decl(neverType.ts, 24, 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))
|
||||
|
||||
return x || error("Undefined value");
|
||||
>x : Symbol(x, Decl(neverType.ts, 30, 18))
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
>f1 : Symbol(f1, Decl(neverType.ts, 32, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
|
||||
if (typeof x === "boolean") {
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
|
||||
x; // never
|
||||
>x : Symbol(x, Decl(neverType.ts, 34, 12))
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: string | number) {
|
||||
>f2 : Symbol(f2, Decl(neverType.ts, 38, 1))
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 12))
|
||||
|
||||
while (true) {
|
||||
if (typeof x === "boolean") {
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 12))
|
||||
|
||||
return x; // never
|
||||
>x : Symbol(x, Decl(neverType.ts, 40, 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))
|
||||
|
||||
let s = cb();
|
||||
>s : Symbol(s, Decl(neverType.ts, 56, 7))
|
||||
>cb : Symbol(cb, Decl(neverType.ts, 55, 14))
|
||||
|
||||
return s;
|
||||
>s : Symbol(s, Decl(neverType.ts, 56, 7))
|
||||
}
|
||||
|
||||
let errorCallback = () => error("Error callback");
|
||||
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 60, 3))
|
||||
>error : Symbol(error, Decl(neverType.ts, 0, 0))
|
||||
|
||||
test(() => "hello");
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
|
||||
test(() => fail());
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 1))
|
||||
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
|
||||
|
||||
test(() => { throw new Error(); })
|
||||
>test : Symbol(test, Decl(neverType.ts, 53, 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))
|
||||
|
||||
189
tests/baselines/reference/neverType.types
Normal file
189
tests/baselines/reference/neverType.types
Normal file
@ -0,0 +1,189 @@
|
||||
=== tests/cases/conformance/types/never/neverType.ts ===
|
||||
|
||||
function error(message: string) {
|
||||
>error : (message: string) => never
|
||||
>message : string
|
||||
|
||||
throw new Error(message);
|
||||
>new Error(message) : Error
|
||||
>Error : ErrorConstructor
|
||||
>message : string
|
||||
}
|
||||
|
||||
function fail() {
|
||||
>fail : () => never
|
||||
|
||||
return error("Something failed");
|
||||
>error("Something failed") : never
|
||||
>error : (message: string) => never
|
||||
>"Something failed" : string
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
>infiniteLoop : () => never
|
||||
|
||||
while (true) {
|
||||
>true : boolean
|
||||
}
|
||||
}
|
||||
|
||||
function move1(direction: "up" | "down") {
|
||||
>move1 : (direction: "up" | "down") => number
|
||||
>direction : "up" | "down"
|
||||
|
||||
switch (direction) {
|
||||
>direction : "up" | "down"
|
||||
|
||||
case "up":
|
||||
>"up" : string
|
||||
|
||||
return 1;
|
||||
>1 : number
|
||||
|
||||
case "down":
|
||||
>"down" : string
|
||||
|
||||
return -1;
|
||||
>-1 : number
|
||||
>1 : number
|
||||
}
|
||||
return error("Should never get here");
|
||||
>error("Should never get here") : never
|
||||
>error : (message: string) => never
|
||||
>"Should never get here" : string
|
||||
}
|
||||
|
||||
function move2(direction: "up" | "down") {
|
||||
>move2 : (direction: "up" | "down") => number
|
||||
>direction : "up" | "down"
|
||||
|
||||
return direction === "up" ? 1 :
|
||||
>direction === "up" ? 1 : direction === "down" ? -1 : error("Should never get here") : number
|
||||
>direction === "up" : boolean
|
||||
>direction : "up" | "down"
|
||||
>"up" : string
|
||||
>1 : number
|
||||
|
||||
direction === "down" ? -1 :
|
||||
>direction === "down" ? -1 : error("Should never get here") : number
|
||||
>direction === "down" : boolean
|
||||
>direction : "up" | "down"
|
||||
>"down" : string
|
||||
>-1 : number
|
||||
>1 : number
|
||||
|
||||
error("Should never get here");
|
||||
>error("Should never get here") : never
|
||||
>error : (message: string) => never
|
||||
>"Should never get here" : string
|
||||
}
|
||||
|
||||
function check<T>(x: T | undefined) {
|
||||
>check : <T>(x: T | undefined) => T
|
||||
>T : T
|
||||
>x : T | undefined
|
||||
>T : T
|
||||
|
||||
return x || error("Undefined value");
|
||||
>x || error("Undefined value") : T
|
||||
>x : T | undefined
|
||||
>error("Undefined value") : never
|
||||
>error : (message: string) => never
|
||||
>"Undefined value" : string
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
>f1 : (x: string | number) => void
|
||||
>x : string | number
|
||||
|
||||
if (typeof x === "boolean") {
|
||||
>typeof x === "boolean" : boolean
|
||||
>typeof x : string
|
||||
>x : string | number
|
||||
>"boolean" : string
|
||||
|
||||
x; // never
|
||||
>x : never
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: string | number) {
|
||||
>f2 : (x: string | number) => never
|
||||
>x : string | number
|
||||
|
||||
while (true) {
|
||||
>true : boolean
|
||||
|
||||
if (typeof x === "boolean") {
|
||||
>typeof x === "boolean" : boolean
|
||||
>typeof x : string
|
||||
>x : string | number
|
||||
>"boolean" : string
|
||||
|
||||
return x; // never
|
||||
>x : 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 test(cb: () => string) {
|
||||
>test : (cb: () => string) => string
|
||||
>cb : () => string
|
||||
|
||||
let s = cb();
|
||||
>s : string
|
||||
>cb() : string
|
||||
>cb : () => string
|
||||
|
||||
return s;
|
||||
>s : string
|
||||
}
|
||||
|
||||
let errorCallback = () => error("Error callback");
|
||||
>errorCallback : () => never
|
||||
>() => error("Error callback") : () => never
|
||||
>error("Error callback") : never
|
||||
>error : (message: string) => never
|
||||
>"Error callback" : string
|
||||
|
||||
test(() => "hello");
|
||||
>test(() => "hello") : string
|
||||
>test : (cb: () => string) => string
|
||||
>() => "hello" : () => string
|
||||
>"hello" : string
|
||||
|
||||
test(() => fail());
|
||||
>test(() => fail()) : string
|
||||
>test : (cb: () => string) => string
|
||||
>() => fail() : () => never
|
||||
>fail() : never
|
||||
>fail : () => never
|
||||
|
||||
test(() => { throw new Error(); })
|
||||
>test(() => { throw new Error(); }) : string
|
||||
>test : (cb: () => string) => string
|
||||
>() => { throw new Error(); } : () => never
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
|
||||
test(errorCallback);
|
||||
>test(errorCallback) : string
|
||||
>test : (cb: () => string) => string
|
||||
>errorCallback : () => never
|
||||
|
||||
50
tests/baselines/reference/neverTypeErrors1.errors.txt
Normal file
50
tests/baselines/reference/neverTypeErrors1.errors.txt
Normal file
@ -0,0 +1,50 @@
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(3,5): error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(4,5): error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(5,5): error TS2322: Type 'boolean' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(6,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(7,5): error TS2322: Type 'null' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(8,5): error TS2322: Type '{}' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(12,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(16,12): error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors1.ts(19,16): error TS2534: A function returning 'never' cannot have a reachable end point.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/never/neverTypeErrors1.ts (9 errors) ====
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
x = "abc";
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
x = false;
|
||||
~
|
||||
!!! error TS2322: Type 'boolean' is not assignable to type 'never'.
|
||||
x = undefined;
|
||||
~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
x = null;
|
||||
~
|
||||
!!! error TS2322: Type 'null' is not assignable to type 'never'.
|
||||
x = {};
|
||||
~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
~~~~~
|
||||
!!! error TS2534: A function returning 'never' cannot have a reachable end point.
|
||||
}
|
||||
40
tests/baselines/reference/neverTypeErrors1.js
Normal file
40
tests/baselines/reference/neverTypeErrors1.js
Normal file
@ -0,0 +1,40 @@
|
||||
//// [neverTypeErrors1.ts]
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
}
|
||||
|
||||
//// [neverTypeErrors1.js]
|
||||
function f1() {
|
||||
var x;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
function f2() {
|
||||
return;
|
||||
}
|
||||
function f3() {
|
||||
return 1;
|
||||
}
|
||||
function f4() {
|
||||
}
|
||||
51
tests/baselines/reference/neverTypeErrors2.errors.txt
Normal file
51
tests/baselines/reference/neverTypeErrors2.errors.txt
Normal file
@ -0,0 +1,51 @@
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(4,5): error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(5,5): error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(6,5): error TS2322: Type 'boolean' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(7,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(8,5): error TS2322: Type 'null' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(9,5): error TS2322: Type '{}' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(13,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(17,12): error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/never/neverTypeErrors2.ts(20,16): error TS2534: A function returning 'never' cannot have a reachable end point.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/never/neverTypeErrors2.ts (9 errors) ====
|
||||
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
x = "abc";
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
x = false;
|
||||
~
|
||||
!!! error TS2322: Type 'boolean' is not assignable to type 'never'.
|
||||
x = undefined;
|
||||
~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
x = null;
|
||||
~
|
||||
!!! error TS2322: Type 'null' is not assignable to type 'never'.
|
||||
x = {};
|
||||
~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
~~~~~
|
||||
!!! error TS2534: A function returning 'never' cannot have a reachable end point.
|
||||
}
|
||||
41
tests/baselines/reference/neverTypeErrors2.js
Normal file
41
tests/baselines/reference/neverTypeErrors2.js
Normal file
@ -0,0 +1,41 @@
|
||||
//// [neverTypeErrors2.ts]
|
||||
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
}
|
||||
|
||||
//// [neverTypeErrors2.js]
|
||||
function f1() {
|
||||
var x;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
function f2() {
|
||||
return;
|
||||
}
|
||||
function f3() {
|
||||
return 1;
|
||||
}
|
||||
function f4() {
|
||||
}
|
||||
@ -7,7 +7,7 @@ while (true) {
|
||||
>true : boolean
|
||||
|
||||
function f() {
|
||||
>f : () => void
|
||||
>f : () => never
|
||||
|
||||
target:
|
||||
>target : any
|
||||
|
||||
@ -63,7 +63,7 @@ var x3 = f1()
|
||||
.then(f2, (e: Error) => {
|
||||
>then : { <TResult>(onfulfilled?: (value: T1) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>; <TResult>(onfulfilled?: (value: T1) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>; }
|
||||
>f2 : (x: T1) => T2
|
||||
>(e: Error) => { throw e;} : (e: Error) => void
|
||||
>(e: Error) => { throw e;} : (e: Error) => never
|
||||
>e : Error
|
||||
>Error : Error
|
||||
|
||||
|
||||
@ -116,6 +116,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : nothing
|
||||
>x : nothing
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@ -110,6 +110,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : nothing
|
||||
>x : nothing
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@ -113,6 +113,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : nothing
|
||||
>x : nothing
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
=== tests/cases/conformance/statements/throwStatements/throwInEnclosingStatements.ts ===
|
||||
|
||||
function fn(x) {
|
||||
>fn : (x: any) => void
|
||||
>fn : (x: any) => never
|
||||
>x : any
|
||||
|
||||
throw x;
|
||||
@ -9,7 +9,7 @@ function fn(x) {
|
||||
}
|
||||
|
||||
<T>(x: T) => { throw x; }
|
||||
><T>(x: T) => { throw x; } : <T>(x: T) => void
|
||||
><T>(x: T) => { throw x; } : <T>(x: T) => never
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
@ -78,7 +78,7 @@ class C<T> {
|
||||
>T : T
|
||||
|
||||
biz() {
|
||||
>biz : () => void
|
||||
>biz : () => never
|
||||
|
||||
throw this.value;
|
||||
>this.value : T
|
||||
@ -93,15 +93,15 @@ class C<T> {
|
||||
}
|
||||
|
||||
var aa = {
|
||||
>aa : { id: number; biz(): void; }
|
||||
>{ id:12, biz() { throw this; }} : { id: number; biz(): void; }
|
||||
>aa : { id: number; biz(): never; }
|
||||
>{ id:12, biz() { throw this; }} : { id: number; biz(): never; }
|
||||
|
||||
id:12,
|
||||
>id : number
|
||||
>12 : number
|
||||
|
||||
biz() {
|
||||
>biz : () => void
|
||||
>biz : () => never
|
||||
|
||||
throw this;
|
||||
>this : any
|
||||
|
||||
@ -121,7 +121,7 @@ if (typeof strOrNum === "boolean") {
|
||||
|
||||
let z1: {} = strOrNum; // {}
|
||||
>z1 : {}
|
||||
>strOrNum : nothing
|
||||
>strOrNum : never
|
||||
}
|
||||
else {
|
||||
let z2: string | number = strOrNum; // string | number
|
||||
@ -215,6 +215,6 @@ if (typeof strOrNum !== "boolean") {
|
||||
else {
|
||||
let z2: {} = strOrNum; // {}
|
||||
>z2 : {}
|
||||
>strOrNum : nothing
|
||||
>strOrNum : never
|
||||
}
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ if (typeof strOrBool === "number") {
|
||||
|
||||
let y1: {} = strOrBool; // {}
|
||||
>y1 : {}
|
||||
>strOrBool : nothing
|
||||
>strOrBool : never
|
||||
}
|
||||
else {
|
||||
let y2: string | boolean = strOrBool; // string | boolean
|
||||
@ -212,6 +212,6 @@ if (typeof strOrBool !== "number") {
|
||||
else {
|
||||
let y2: {} = strOrBool; // {}
|
||||
>y2 : {}
|
||||
>strOrBool : nothing
|
||||
>strOrBool : never
|
||||
}
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ if (typeof strOrNumOrBool === "Object") {
|
||||
|
||||
let q1: {} = strOrNumOrBool; // {}
|
||||
>q1 : {}
|
||||
>strOrNumOrBool : nothing
|
||||
>strOrNumOrBool : never
|
||||
}
|
||||
else {
|
||||
let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean
|
||||
@ -178,6 +178,6 @@ if (typeof strOrNumOrBool !== "Object") {
|
||||
else {
|
||||
let q2: {} = strOrNumOrBool; // {}
|
||||
>q2 : {}
|
||||
>strOrNumOrBool : nothing
|
||||
>strOrNumOrBool : never
|
||||
}
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ if (typeof numOrBool === "string") {
|
||||
|
||||
let x1: {} = numOrBool; // {}
|
||||
>x1 : {}
|
||||
>numOrBool : nothing
|
||||
>numOrBool : never
|
||||
}
|
||||
else {
|
||||
let x2: number | boolean = numOrBool; // number | boolean
|
||||
@ -214,6 +214,6 @@ if (typeof numOrBool !== "string") {
|
||||
else {
|
||||
let x2: {} = numOrBool; // {}
|
||||
>x2 : {}
|
||||
>numOrBool : nothing
|
||||
>numOrBool : never
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +259,7 @@ function f4() {
|
||||
>"boolean" : string
|
||||
|
||||
x; // nothing (boolean not in declared type)
|
||||
>x : nothing
|
||||
>x : never
|
||||
}
|
||||
x; // undefined
|
||||
>x : undefined
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'nothing'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ====
|
||||
@ -10,5 +10,5 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20)
|
||||
result = result2;
|
||||
} else if (!result.global) {
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'global' does not exist on type 'nothing'.
|
||||
!!! error TS2339: Property 'global' does not exist on type 'never'.
|
||||
}
|
||||
68
tests/cases/conformance/types/never/neverType.ts
Normal file
68
tests/cases/conformance/types/never/neverType.ts
Normal file
@ -0,0 +1,68 @@
|
||||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
function error(message: string) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function fail() {
|
||||
return error("Something failed");
|
||||
}
|
||||
|
||||
function infiniteLoop() {
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
function move1(direction: "up" | "down") {
|
||||
switch (direction) {
|
||||
case "up":
|
||||
return 1;
|
||||
case "down":
|
||||
return -1;
|
||||
}
|
||||
return error("Should never get here");
|
||||
}
|
||||
|
||||
function move2(direction: "up" | "down") {
|
||||
return direction === "up" ? 1 :
|
||||
direction === "down" ? -1 :
|
||||
error("Should never get here");
|
||||
}
|
||||
|
||||
function check<T>(x: T | undefined) {
|
||||
return x || error("Undefined value");
|
||||
}
|
||||
|
||||
function f1(x: string | number) {
|
||||
if (typeof x === "boolean") {
|
||||
x; // never
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: string | number) {
|
||||
while (true) {
|
||||
if (typeof x === "boolean") {
|
||||
return x; // never
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function failOrThrow(shouldFail: boolean) {
|
||||
if (shouldFail) {
|
||||
return fail();
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function test(cb: () => string) {
|
||||
let s = cb();
|
||||
return s;
|
||||
}
|
||||
|
||||
let errorCallback = () => error("Error callback");
|
||||
|
||||
test(() => "hello");
|
||||
test(() => fail());
|
||||
test(() => { throw new Error(); })
|
||||
test(errorCallback);
|
||||
20
tests/cases/conformance/types/never/neverTypeErrors1.ts
Normal file
20
tests/cases/conformance/types/never/neverTypeErrors1.ts
Normal file
@ -0,0 +1,20 @@
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
}
|
||||
22
tests/cases/conformance/types/never/neverTypeErrors2.ts
Normal file
22
tests/cases/conformance/types/never/neverTypeErrors2.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// @strictNullChecks: true
|
||||
|
||||
function f1() {
|
||||
let x: never;
|
||||
x = 1;
|
||||
x = "abc";
|
||||
x = false;
|
||||
x = undefined;
|
||||
x = null;
|
||||
x = {};
|
||||
}
|
||||
|
||||
function f2(): never {
|
||||
return;
|
||||
}
|
||||
|
||||
function f3(): never {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function f4(): never {
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user