diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7aa83ad268e..a916b898d80 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -120,9 +120,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 neverType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); emptyGenericType.instantiations = {}; @@ -2029,12 +2029,7 @@ namespace ts { writeUnionOrIntersectionType(type, flags); } else if (type.flags & TypeFlags.Anonymous) { - if (type === neverType) { - writer.writeKeyword("never"); - } - else { - writeAnonymousType(type, flags); - } + writeAnonymousType(type, flags); } else if (type.flags & TypeFlags.StringLiteral) { writer.writeStringLiteral(`"${escapeString((type).text)}"`); @@ -5862,28 +5857,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) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fbe1f3c60c8..b23c2fa3a67 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2171,11 +2171,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,