Merge pull request #26941 from jack-williams/narrow-unknown-with-triple-equals
Fix #25172: Add narrowing for `unknown` with triple equals
This commit is contained in:
commit
0df89cc96f
|
@ -16057,6 +16057,15 @@ namespace ts {
|
|||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const valueType = getTypeOfExpression(value);
|
||||
if ((type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsEqualsToken) && assumeTrue) {
|
||||
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) {
|
||||
return valueType;
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Object) {
|
||||
return nonPrimitiveType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Nullable) {
|
||||
if (!strictNullChecks) {
|
||||
return type;
|
||||
|
|
189
tests/baselines/reference/unknownType2.js
Normal file
189
tests/baselines/reference/unknownType2.js
Normal file
|
@ -0,0 +1,189 @@
|
|||
//// [unknownType2.ts]
|
||||
type isUnknown<T> = unknown extends T ? true : false;
|
||||
type isTrue<T extends true> = T;
|
||||
|
||||
type SomeResponse = 'yes' | 'no' | 'idk';
|
||||
let validate: (x: unknown) => SomeResponse = x => (x === 'yes' || x === 'no') ? x : 'idk'; // No error
|
||||
|
||||
const u: unknown = undefined;
|
||||
|
||||
declare const symb: unique symbol;
|
||||
|
||||
if (u === 5) {
|
||||
const y = u.toString(10);
|
||||
}
|
||||
|
||||
if (u === true || u === false) {
|
||||
const someBool: boolean = u;
|
||||
}
|
||||
|
||||
if (u === undefined) {
|
||||
const undef: undefined = u;
|
||||
}
|
||||
|
||||
if (u === null) {
|
||||
const someNull: null = u;
|
||||
}
|
||||
|
||||
if (u === symb) {
|
||||
const symbolAlias: typeof symb = u;
|
||||
}
|
||||
|
||||
if (!(u === 42)) {
|
||||
type A = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u !== 42) {
|
||||
type B = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == 42) {
|
||||
type C = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == true) {
|
||||
type D = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == Object) {
|
||||
type E = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
declare const aString: string;
|
||||
declare const aBoolean: boolean;
|
||||
declare const aNumber: number;
|
||||
declare const anObject: object;
|
||||
declare const anObjectLiteral: { x: number };
|
||||
declare const aUnion: { x: number } | { y: string };
|
||||
declare const anIntersection: { x: number } & { y: string };
|
||||
declare const aFunction: () => number;
|
||||
|
||||
if (u === aString) {
|
||||
let uString: string = u;
|
||||
}
|
||||
|
||||
if (u === aBoolean) {
|
||||
let uString: boolean = u;
|
||||
}
|
||||
|
||||
if (u === aNumber) {
|
||||
let uNumber: number = u;
|
||||
}
|
||||
|
||||
if (u === anObject) {
|
||||
let uObject: object = u;
|
||||
}
|
||||
|
||||
if (u === anObjectLiteral) {
|
||||
let uObjectLiteral: object = u;
|
||||
}
|
||||
|
||||
if (u === aUnion) {
|
||||
type unionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u === anIntersection) {
|
||||
type intersectionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u === aFunction) {
|
||||
let uFunction: object = u;
|
||||
}
|
||||
|
||||
enum NumberEnum {
|
||||
A,
|
||||
B,
|
||||
C
|
||||
}
|
||||
|
||||
enum StringEnum {
|
||||
A = "A",
|
||||
B = "B",
|
||||
C = "C"
|
||||
}
|
||||
|
||||
if (u === NumberEnum || u === StringEnum) {
|
||||
let enumObj: object = u;
|
||||
}
|
||||
|
||||
if(u === NumberEnum.A) {
|
||||
let a: NumberEnum.A = u
|
||||
}
|
||||
|
||||
if(u === StringEnum.B) {
|
||||
let b: StringEnum.B = u
|
||||
}
|
||||
|
||||
|
||||
//// [unknownType2.js]
|
||||
"use strict";
|
||||
var validate = function (x) { return (x === 'yes' || x === 'no') ? x : 'idk'; }; // No error
|
||||
var u = undefined;
|
||||
if (u === 5) {
|
||||
var y = u.toString(10);
|
||||
}
|
||||
if (u === true || u === false) {
|
||||
var someBool = u;
|
||||
}
|
||||
if (u === undefined) {
|
||||
var undef = u;
|
||||
}
|
||||
if (u === null) {
|
||||
var someNull = u;
|
||||
}
|
||||
if (u === symb) {
|
||||
var symbolAlias = u;
|
||||
}
|
||||
if (!(u === 42)) {
|
||||
}
|
||||
if (u !== 42) {
|
||||
}
|
||||
if (u == 42) {
|
||||
}
|
||||
if (u == true) {
|
||||
}
|
||||
if (u == Object) {
|
||||
}
|
||||
if (u === aString) {
|
||||
var uString = u;
|
||||
}
|
||||
if (u === aBoolean) {
|
||||
var uString = u;
|
||||
}
|
||||
if (u === aNumber) {
|
||||
var uNumber = u;
|
||||
}
|
||||
if (u === anObject) {
|
||||
var uObject = u;
|
||||
}
|
||||
if (u === anObjectLiteral) {
|
||||
var uObjectLiteral = u;
|
||||
}
|
||||
if (u === aUnion) {
|
||||
}
|
||||
if (u === anIntersection) {
|
||||
}
|
||||
if (u === aFunction) {
|
||||
var uFunction = u;
|
||||
}
|
||||
var NumberEnum;
|
||||
(function (NumberEnum) {
|
||||
NumberEnum[NumberEnum["A"] = 0] = "A";
|
||||
NumberEnum[NumberEnum["B"] = 1] = "B";
|
||||
NumberEnum[NumberEnum["C"] = 2] = "C";
|
||||
})(NumberEnum || (NumberEnum = {}));
|
||||
var StringEnum;
|
||||
(function (StringEnum) {
|
||||
StringEnum["A"] = "A";
|
||||
StringEnum["B"] = "B";
|
||||
StringEnum["C"] = "C";
|
||||
})(StringEnum || (StringEnum = {}));
|
||||
if (u === NumberEnum || u === StringEnum) {
|
||||
var enumObj = u;
|
||||
}
|
||||
if (u === NumberEnum.A) {
|
||||
var a = u;
|
||||
}
|
||||
if (u === StringEnum.B) {
|
||||
var b = u;
|
||||
}
|
295
tests/baselines/reference/unknownType2.symbols
Normal file
295
tests/baselines/reference/unknownType2.symbols
Normal file
|
@ -0,0 +1,295 @@
|
|||
=== tests/cases/conformance/types/unknown/unknownType2.ts ===
|
||||
type isUnknown<T> = unknown extends T ? true : false;
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(unknownType2.ts, 0, 15))
|
||||
>T : Symbol(T, Decl(unknownType2.ts, 0, 15))
|
||||
|
||||
type isTrue<T extends true> = T;
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>T : Symbol(T, Decl(unknownType2.ts, 1, 12))
|
||||
>T : Symbol(T, Decl(unknownType2.ts, 1, 12))
|
||||
|
||||
type SomeResponse = 'yes' | 'no' | 'idk';
|
||||
>SomeResponse : Symbol(SomeResponse, Decl(unknownType2.ts, 1, 32))
|
||||
|
||||
let validate: (x: unknown) => SomeResponse = x => (x === 'yes' || x === 'no') ? x : 'idk'; // No error
|
||||
>validate : Symbol(validate, Decl(unknownType2.ts, 4, 3))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 4, 15))
|
||||
>SomeResponse : Symbol(SomeResponse, Decl(unknownType2.ts, 1, 32))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 4, 44))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 4, 44))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 4, 44))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 4, 44))
|
||||
|
||||
const u: unknown = undefined;
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
declare const symb: unique symbol;
|
||||
>symb : Symbol(symb, Decl(unknownType2.ts, 8, 13))
|
||||
|
||||
if (u === 5) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
const y = u.toString(10);
|
||||
>y : Symbol(y, Decl(unknownType2.ts, 11, 9))
|
||||
>u.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
if (u === true || u === false) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
const someBool: boolean = u;
|
||||
>someBool : Symbol(someBool, Decl(unknownType2.ts, 15, 9))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === undefined) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
const undef: undefined = u;
|
||||
>undef : Symbol(undef, Decl(unknownType2.ts, 19, 9))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === null) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
const someNull: null = u;
|
||||
>someNull : Symbol(someNull, Decl(unknownType2.ts, 23, 9))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === symb) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>symb : Symbol(symb, Decl(unknownType2.ts, 8, 13))
|
||||
|
||||
const symbolAlias: typeof symb = u;
|
||||
>symbolAlias : Symbol(symbolAlias, Decl(unknownType2.ts, 27, 9))
|
||||
>symb : Symbol(symb, Decl(unknownType2.ts, 8, 13))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (!(u === 42)) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
type A = isTrue<isUnknown<typeof u>>
|
||||
>A : Symbol(A, Decl(unknownType2.ts, 30, 18))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u !== 42) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
type B = isTrue<isUnknown<typeof u>>
|
||||
>B : Symbol(B, Decl(unknownType2.ts, 34, 15))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u == 42) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
type C = isTrue<isUnknown<typeof u>>
|
||||
>C : Symbol(C, Decl(unknownType2.ts, 38, 14))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u == true) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
|
||||
type D = isTrue<isUnknown<typeof u>>
|
||||
>D : Symbol(D, Decl(unknownType2.ts, 42, 16))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u == Object) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
type E = isTrue<isUnknown<typeof u>>
|
||||
>E : Symbol(E, Decl(unknownType2.ts, 46, 18))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
declare const aString: string;
|
||||
>aString : Symbol(aString, Decl(unknownType2.ts, 50, 13))
|
||||
|
||||
declare const aBoolean: boolean;
|
||||
>aBoolean : Symbol(aBoolean, Decl(unknownType2.ts, 51, 13))
|
||||
|
||||
declare const aNumber: number;
|
||||
>aNumber : Symbol(aNumber, Decl(unknownType2.ts, 52, 13))
|
||||
|
||||
declare const anObject: object;
|
||||
>anObject : Symbol(anObject, Decl(unknownType2.ts, 53, 13))
|
||||
|
||||
declare const anObjectLiteral: { x: number };
|
||||
>anObjectLiteral : Symbol(anObjectLiteral, Decl(unknownType2.ts, 54, 13))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 54, 32))
|
||||
|
||||
declare const aUnion: { x: number } | { y: string };
|
||||
>aUnion : Symbol(aUnion, Decl(unknownType2.ts, 55, 13))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 55, 23))
|
||||
>y : Symbol(y, Decl(unknownType2.ts, 55, 39))
|
||||
|
||||
declare const anIntersection: { x: number } & { y: string };
|
||||
>anIntersection : Symbol(anIntersection, Decl(unknownType2.ts, 56, 13))
|
||||
>x : Symbol(x, Decl(unknownType2.ts, 56, 31))
|
||||
>y : Symbol(y, Decl(unknownType2.ts, 56, 47))
|
||||
|
||||
declare const aFunction: () => number;
|
||||
>aFunction : Symbol(aFunction, Decl(unknownType2.ts, 57, 13))
|
||||
|
||||
if (u === aString) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>aString : Symbol(aString, Decl(unknownType2.ts, 50, 13))
|
||||
|
||||
let uString: string = u;
|
||||
>uString : Symbol(uString, Decl(unknownType2.ts, 60, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === aBoolean) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>aBoolean : Symbol(aBoolean, Decl(unknownType2.ts, 51, 13))
|
||||
|
||||
let uString: boolean = u;
|
||||
>uString : Symbol(uString, Decl(unknownType2.ts, 64, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === aNumber) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>aNumber : Symbol(aNumber, Decl(unknownType2.ts, 52, 13))
|
||||
|
||||
let uNumber: number = u;
|
||||
>uNumber : Symbol(uNumber, Decl(unknownType2.ts, 68, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === anObject) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>anObject : Symbol(anObject, Decl(unknownType2.ts, 53, 13))
|
||||
|
||||
let uObject: object = u;
|
||||
>uObject : Symbol(uObject, Decl(unknownType2.ts, 72, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === anObjectLiteral) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>anObjectLiteral : Symbol(anObjectLiteral, Decl(unknownType2.ts, 54, 13))
|
||||
|
||||
let uObjectLiteral: object = u;
|
||||
>uObjectLiteral : Symbol(uObjectLiteral, Decl(unknownType2.ts, 76, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === aUnion) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>aUnion : Symbol(aUnion, Decl(unknownType2.ts, 55, 13))
|
||||
|
||||
type unionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
>unionDoesNotNarrow : Symbol(unionDoesNotNarrow, Decl(unknownType2.ts, 79, 19))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === anIntersection) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>anIntersection : Symbol(anIntersection, Decl(unknownType2.ts, 56, 13))
|
||||
|
||||
type intersectionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
>intersectionDoesNotNarrow : Symbol(intersectionDoesNotNarrow, Decl(unknownType2.ts, 83, 27))
|
||||
>isTrue : Symbol(isTrue, Decl(unknownType2.ts, 0, 53))
|
||||
>isUnknown : Symbol(isUnknown, Decl(unknownType2.ts, 0, 0))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if (u === aFunction) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>aFunction : Symbol(aFunction, Decl(unknownType2.ts, 57, 13))
|
||||
|
||||
let uFunction: object = u;
|
||||
>uFunction : Symbol(uFunction, Decl(unknownType2.ts, 88, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
enum NumberEnum {
|
||||
>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 89, 1))
|
||||
|
||||
A,
|
||||
>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 91, 17))
|
||||
|
||||
B,
|
||||
>B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 92, 6))
|
||||
|
||||
C
|
||||
>C : Symbol(NumberEnum.C, Decl(unknownType2.ts, 93, 6))
|
||||
}
|
||||
|
||||
enum StringEnum {
|
||||
>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 95, 1))
|
||||
|
||||
A = "A",
|
||||
>A : Symbol(StringEnum.A, Decl(unknownType2.ts, 97, 17))
|
||||
|
||||
B = "B",
|
||||
>B : Symbol(StringEnum.B, Decl(unknownType2.ts, 98, 12))
|
||||
|
||||
C = "C"
|
||||
>C : Symbol(StringEnum.C, Decl(unknownType2.ts, 99, 12))
|
||||
}
|
||||
|
||||
if (u === NumberEnum || u === StringEnum) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 89, 1))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 95, 1))
|
||||
|
||||
let enumObj: object = u;
|
||||
>enumObj : Symbol(enumObj, Decl(unknownType2.ts, 104, 7))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if(u === NumberEnum.A) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>NumberEnum.A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 91, 17))
|
||||
>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 89, 1))
|
||||
>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 91, 17))
|
||||
|
||||
let a: NumberEnum.A = u
|
||||
>a : Symbol(a, Decl(unknownType2.ts, 108, 7))
|
||||
>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 89, 1))
|
||||
>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 91, 17))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
||||
if(u === StringEnum.B) {
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
>StringEnum.B : Symbol(StringEnum.B, Decl(unknownType2.ts, 98, 12))
|
||||
>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 95, 1))
|
||||
>B : Symbol(StringEnum.B, Decl(unknownType2.ts, 98, 12))
|
||||
|
||||
let b: StringEnum.B = u
|
||||
>b : Symbol(b, Decl(unknownType2.ts, 112, 7))
|
||||
>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 95, 1))
|
||||
>B : Symbol(StringEnum.B, Decl(unknownType2.ts, 98, 12))
|
||||
>u : Symbol(u, Decl(unknownType2.ts, 6, 5))
|
||||
}
|
||||
|
327
tests/baselines/reference/unknownType2.types
Normal file
327
tests/baselines/reference/unknownType2.types
Normal file
|
@ -0,0 +1,327 @@
|
|||
=== tests/cases/conformance/types/unknown/unknownType2.ts ===
|
||||
type isUnknown<T> = unknown extends T ? true : false;
|
||||
>isUnknown : isUnknown<T>
|
||||
>true : true
|
||||
>false : false
|
||||
|
||||
type isTrue<T extends true> = T;
|
||||
>isTrue : T
|
||||
>true : true
|
||||
|
||||
type SomeResponse = 'yes' | 'no' | 'idk';
|
||||
>SomeResponse : SomeResponse
|
||||
|
||||
let validate: (x: unknown) => SomeResponse = x => (x === 'yes' || x === 'no') ? x : 'idk'; // No error
|
||||
>validate : (x: unknown) => SomeResponse
|
||||
>x : unknown
|
||||
>x => (x === 'yes' || x === 'no') ? x : 'idk' : (x: unknown) => "yes" | "no" | "idk"
|
||||
>x : unknown
|
||||
>(x === 'yes' || x === 'no') ? x : 'idk' : SomeResponse
|
||||
>(x === 'yes' || x === 'no') : boolean
|
||||
>x === 'yes' || x === 'no' : boolean
|
||||
>x === 'yes' : boolean
|
||||
>x : unknown
|
||||
>'yes' : "yes"
|
||||
>x === 'no' : boolean
|
||||
>x : unknown
|
||||
>'no' : "no"
|
||||
>x : "yes" | "no"
|
||||
>'idk' : "idk"
|
||||
|
||||
const u: unknown = undefined;
|
||||
>u : unknown
|
||||
>undefined : undefined
|
||||
|
||||
declare const symb: unique symbol;
|
||||
>symb : unique symbol
|
||||
|
||||
if (u === 5) {
|
||||
>u === 5 : boolean
|
||||
>u : unknown
|
||||
>5 : 5
|
||||
|
||||
const y = u.toString(10);
|
||||
>y : string
|
||||
>u.toString(10) : string
|
||||
>u.toString : (radix?: number | undefined) => string
|
||||
>u : 5
|
||||
>toString : (radix?: number | undefined) => string
|
||||
>10 : 10
|
||||
}
|
||||
|
||||
if (u === true || u === false) {
|
||||
>u === true || u === false : boolean
|
||||
>u === true : boolean
|
||||
>u : unknown
|
||||
>true : true
|
||||
>u === false : boolean
|
||||
>u : unknown
|
||||
>false : false
|
||||
|
||||
const someBool: boolean = u;
|
||||
>someBool : boolean
|
||||
>u : boolean
|
||||
}
|
||||
|
||||
if (u === undefined) {
|
||||
>u === undefined : boolean
|
||||
>u : unknown
|
||||
>undefined : undefined
|
||||
|
||||
const undef: undefined = u;
|
||||
>undef : undefined
|
||||
>u : undefined
|
||||
}
|
||||
|
||||
if (u === null) {
|
||||
>u === null : boolean
|
||||
>u : unknown
|
||||
>null : null
|
||||
|
||||
const someNull: null = u;
|
||||
>someNull : null
|
||||
>null : null
|
||||
>u : null
|
||||
}
|
||||
|
||||
if (u === symb) {
|
||||
>u === symb : boolean
|
||||
>u : unknown
|
||||
>symb : unique symbol
|
||||
|
||||
const symbolAlias: typeof symb = u;
|
||||
>symbolAlias : unique symbol
|
||||
>symb : unique symbol
|
||||
>u : unique symbol
|
||||
}
|
||||
|
||||
if (!(u === 42)) {
|
||||
>!(u === 42) : boolean
|
||||
>(u === 42) : boolean
|
||||
>u === 42 : boolean
|
||||
>u : unknown
|
||||
>42 : 42
|
||||
|
||||
type A = isTrue<isUnknown<typeof u>>
|
||||
>A : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u !== 42) {
|
||||
>u !== 42 : boolean
|
||||
>u : unknown
|
||||
>42 : 42
|
||||
|
||||
type B = isTrue<isUnknown<typeof u>>
|
||||
>B : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u == 42) {
|
||||
>u == 42 : boolean
|
||||
>u : unknown
|
||||
>42 : 42
|
||||
|
||||
type C = isTrue<isUnknown<typeof u>>
|
||||
>C : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u == true) {
|
||||
>u == true : boolean
|
||||
>u : unknown
|
||||
>true : true
|
||||
|
||||
type D = isTrue<isUnknown<typeof u>>
|
||||
>D : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u == Object) {
|
||||
>u == Object : boolean
|
||||
>u : unknown
|
||||
>Object : ObjectConstructor
|
||||
|
||||
type E = isTrue<isUnknown<typeof u>>
|
||||
>E : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
declare const aString: string;
|
||||
>aString : string
|
||||
|
||||
declare const aBoolean: boolean;
|
||||
>aBoolean : boolean
|
||||
|
||||
declare const aNumber: number;
|
||||
>aNumber : number
|
||||
|
||||
declare const anObject: object;
|
||||
>anObject : object
|
||||
|
||||
declare const anObjectLiteral: { x: number };
|
||||
>anObjectLiteral : { x: number; }
|
||||
>x : number
|
||||
|
||||
declare const aUnion: { x: number } | { y: string };
|
||||
>aUnion : { x: number; } | { y: string; }
|
||||
>x : number
|
||||
>y : string
|
||||
|
||||
declare const anIntersection: { x: number } & { y: string };
|
||||
>anIntersection : { x: number; } & { y: string; }
|
||||
>x : number
|
||||
>y : string
|
||||
|
||||
declare const aFunction: () => number;
|
||||
>aFunction : () => number
|
||||
|
||||
if (u === aString) {
|
||||
>u === aString : boolean
|
||||
>u : unknown
|
||||
>aString : string
|
||||
|
||||
let uString: string = u;
|
||||
>uString : string
|
||||
>u : string
|
||||
}
|
||||
|
||||
if (u === aBoolean) {
|
||||
>u === aBoolean : boolean
|
||||
>u : unknown
|
||||
>aBoolean : boolean
|
||||
|
||||
let uString: boolean = u;
|
||||
>uString : boolean
|
||||
>u : boolean
|
||||
}
|
||||
|
||||
if (u === aNumber) {
|
||||
>u === aNumber : boolean
|
||||
>u : unknown
|
||||
>aNumber : number
|
||||
|
||||
let uNumber: number = u;
|
||||
>uNumber : number
|
||||
>u : number
|
||||
}
|
||||
|
||||
if (u === anObject) {
|
||||
>u === anObject : boolean
|
||||
>u : unknown
|
||||
>anObject : object
|
||||
|
||||
let uObject: object = u;
|
||||
>uObject : object
|
||||
>u : object
|
||||
}
|
||||
|
||||
if (u === anObjectLiteral) {
|
||||
>u === anObjectLiteral : boolean
|
||||
>u : unknown
|
||||
>anObjectLiteral : { x: number; }
|
||||
|
||||
let uObjectLiteral: object = u;
|
||||
>uObjectLiteral : object
|
||||
>u : object
|
||||
}
|
||||
|
||||
if (u === aUnion) {
|
||||
>u === aUnion : boolean
|
||||
>u : unknown
|
||||
>aUnion : { x: number; } | { y: string; }
|
||||
|
||||
type unionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
>unionDoesNotNarrow : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u === anIntersection) {
|
||||
>u === anIntersection : boolean
|
||||
>u : unknown
|
||||
>anIntersection : { x: number; } & { y: string; }
|
||||
|
||||
type intersectionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
>intersectionDoesNotNarrow : true
|
||||
>u : unknown
|
||||
}
|
||||
|
||||
if (u === aFunction) {
|
||||
>u === aFunction : boolean
|
||||
>u : unknown
|
||||
>aFunction : () => number
|
||||
|
||||
let uFunction: object = u;
|
||||
>uFunction : object
|
||||
>u : object
|
||||
}
|
||||
|
||||
enum NumberEnum {
|
||||
>NumberEnum : NumberEnum
|
||||
|
||||
A,
|
||||
>A : NumberEnum.A
|
||||
|
||||
B,
|
||||
>B : NumberEnum.B
|
||||
|
||||
C
|
||||
>C : NumberEnum.C
|
||||
}
|
||||
|
||||
enum StringEnum {
|
||||
>StringEnum : StringEnum
|
||||
|
||||
A = "A",
|
||||
>A : StringEnum.A
|
||||
>"A" : "A"
|
||||
|
||||
B = "B",
|
||||
>B : StringEnum.B
|
||||
>"B" : "B"
|
||||
|
||||
C = "C"
|
||||
>C : StringEnum.C
|
||||
>"C" : "C"
|
||||
}
|
||||
|
||||
if (u === NumberEnum || u === StringEnum) {
|
||||
>u === NumberEnum || u === StringEnum : boolean
|
||||
>u === NumberEnum : boolean
|
||||
>u : unknown
|
||||
>NumberEnum : typeof NumberEnum
|
||||
>u === StringEnum : boolean
|
||||
>u : unknown
|
||||
>StringEnum : typeof StringEnum
|
||||
|
||||
let enumObj: object = u;
|
||||
>enumObj : object
|
||||
>u : object
|
||||
}
|
||||
|
||||
if(u === NumberEnum.A) {
|
||||
>u === NumberEnum.A : boolean
|
||||
>u : unknown
|
||||
>NumberEnum.A : NumberEnum.A
|
||||
>NumberEnum : typeof NumberEnum
|
||||
>A : NumberEnum.A
|
||||
|
||||
let a: NumberEnum.A = u
|
||||
>a : NumberEnum.A
|
||||
>NumberEnum : any
|
||||
>u : NumberEnum.A
|
||||
}
|
||||
|
||||
if(u === StringEnum.B) {
|
||||
>u === StringEnum.B : boolean
|
||||
>u : unknown
|
||||
>StringEnum.B : StringEnum.B
|
||||
>StringEnum : typeof StringEnum
|
||||
>B : StringEnum.B
|
||||
|
||||
let b: StringEnum.B = u
|
||||
>b : StringEnum.B
|
||||
>StringEnum : any
|
||||
>u : StringEnum.B
|
||||
}
|
||||
|
116
tests/cases/conformance/types/unknown/unknownType2.ts
Normal file
116
tests/cases/conformance/types/unknown/unknownType2.ts
Normal file
|
@ -0,0 +1,116 @@
|
|||
// @strict: true
|
||||
|
||||
type isUnknown<T> = unknown extends T ? true : false;
|
||||
type isTrue<T extends true> = T;
|
||||
|
||||
type SomeResponse = 'yes' | 'no' | 'idk';
|
||||
let validate: (x: unknown) => SomeResponse = x => (x === 'yes' || x === 'no') ? x : 'idk'; // No error
|
||||
|
||||
const u: unknown = undefined;
|
||||
|
||||
declare const symb: unique symbol;
|
||||
|
||||
if (u === 5) {
|
||||
const y = u.toString(10);
|
||||
}
|
||||
|
||||
if (u === true || u === false) {
|
||||
const someBool: boolean = u;
|
||||
}
|
||||
|
||||
if (u === undefined) {
|
||||
const undef: undefined = u;
|
||||
}
|
||||
|
||||
if (u === null) {
|
||||
const someNull: null = u;
|
||||
}
|
||||
|
||||
if (u === symb) {
|
||||
const symbolAlias: typeof symb = u;
|
||||
}
|
||||
|
||||
if (!(u === 42)) {
|
||||
type A = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u !== 42) {
|
||||
type B = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == 42) {
|
||||
type C = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == true) {
|
||||
type D = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u == Object) {
|
||||
type E = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
declare const aString: string;
|
||||
declare const aBoolean: boolean;
|
||||
declare const aNumber: number;
|
||||
declare const anObject: object;
|
||||
declare const anObjectLiteral: { x: number };
|
||||
declare const aUnion: { x: number } | { y: string };
|
||||
declare const anIntersection: { x: number } & { y: string };
|
||||
declare const aFunction: () => number;
|
||||
|
||||
if (u === aString) {
|
||||
let uString: string = u;
|
||||
}
|
||||
|
||||
if (u === aBoolean) {
|
||||
let uString: boolean = u;
|
||||
}
|
||||
|
||||
if (u === aNumber) {
|
||||
let uNumber: number = u;
|
||||
}
|
||||
|
||||
if (u === anObject) {
|
||||
let uObject: object = u;
|
||||
}
|
||||
|
||||
if (u === anObjectLiteral) {
|
||||
let uObjectLiteral: object = u;
|
||||
}
|
||||
|
||||
if (u === aUnion) {
|
||||
type unionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u === anIntersection) {
|
||||
type intersectionDoesNotNarrow = isTrue<isUnknown<typeof u>>
|
||||
}
|
||||
|
||||
if (u === aFunction) {
|
||||
let uFunction: object = u;
|
||||
}
|
||||
|
||||
enum NumberEnum {
|
||||
A,
|
||||
B,
|
||||
C
|
||||
}
|
||||
|
||||
enum StringEnum {
|
||||
A = "A",
|
||||
B = "B",
|
||||
C = "C"
|
||||
}
|
||||
|
||||
if (u === NumberEnum || u === StringEnum) {
|
||||
let enumObj: object = u;
|
||||
}
|
||||
|
||||
if(u === NumberEnum.A) {
|
||||
let a: NumberEnum.A = u
|
||||
}
|
||||
|
||||
if(u === StringEnum.B) {
|
||||
let b: StringEnum.B = u
|
||||
}
|
Loading…
Reference in a new issue