a4f9bf0fce
* Create type aliases for unresolved type symbols * Accept new baselines * Update fourslash tests * Unresolved import aliases create tagged unresolved symbols * Add comments * Accept new baselines * Add fourslash tests
392 lines
7.5 KiB
Plaintext
392 lines
7.5 KiB
Plaintext
=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts ===
|
||
class A {
|
||
>A : A
|
||
|
||
propA: number;
|
||
>propA : number
|
||
}
|
||
|
||
class B {
|
||
>B : B
|
||
|
||
propB: number;
|
||
>propB : number
|
||
}
|
||
|
||
class C extends A {
|
||
>C : C
|
||
>A : A
|
||
|
||
propC: number;
|
||
>propC : number
|
||
}
|
||
|
||
function hasANonBooleanReturnStatement(x): x is A {
|
||
>hasANonBooleanReturnStatement : (x: any) => x is A
|
||
>x : any
|
||
|
||
return '';
|
||
>'' : ""
|
||
}
|
||
|
||
function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A {
|
||
>hasTypeGuardTypeInsideTypeGuardType : (x: any) => x is x
|
||
>x : any
|
||
>is : any
|
||
>A : typeof A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasMissingIsKeyword(): x {
|
||
>hasMissingIsKeyword : () => x
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasMissingParameter(): x is A {
|
||
>hasMissingParameter : () => x is A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasMissingTypeInTypeGuardType(x): x is {
|
||
>hasMissingTypeInTypeGuardType : (x: any) => x is {}
|
||
>x : any
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasNonMatchingParameter(y): x is A {
|
||
>hasNonMatchingParameter : (y: any) => x is A
|
||
>y : any
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasNonMatchingParameterType1(x: A): x is B {
|
||
>hasNonMatchingParameterType1 : (x: A) => x is B
|
||
>x : A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasNonMatchingParameterType2(x: string): x is number {
|
||
>hasNonMatchingParameterType2 : (x: string) => x is number
|
||
>x : string
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function hasNonMathcingGenericType<T>(a: string): a is T[] {
|
||
>hasNonMathcingGenericType : <T>(a: string) => a is T[]
|
||
>a : string
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
let a: A;
|
||
>a : A
|
||
|
||
let b: B;
|
||
>b : B
|
||
|
||
declare function isB(p1): p1 is B;
|
||
>isB : (p1: any) => p1 is B
|
||
>p1 : any
|
||
|
||
declare function isC(p1): p1 is C;
|
||
>isC : (p1: any) => p1 is C
|
||
>p1 : any
|
||
|
||
declare function funA(p1: any, p2: any): p1 is B;
|
||
>funA : (p1: any, p2: any) => p1 is B
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
declare function hasNoTypeGuard(x);
|
||
>hasNoTypeGuard : (x: any) => any
|
||
>x : any
|
||
|
||
// Passed argument is not the same as the one being guarded.
|
||
if (isB(b)) {
|
||
>isB(b) : boolean
|
||
>isB : (p1: any) => p1 is B
|
||
>b : B
|
||
|
||
a.propB;
|
||
>a.propB : any
|
||
>a : A
|
||
>propB : any
|
||
}
|
||
|
||
// Parameter index and argument index for the type guard target is not matching.
|
||
if (funA(0, a)) {
|
||
>funA(0, a) : boolean
|
||
>funA : (p1: any, p2: any) => p1 is B
|
||
>0 : 0
|
||
>a : A
|
||
|
||
a.propB; // Error
|
||
>a.propB : any
|
||
>a : A
|
||
>propB : any
|
||
}
|
||
|
||
// No type guard in if statement
|
||
if (hasNoTypeGuard(a)) {
|
||
>hasNoTypeGuard(a) : any
|
||
>hasNoTypeGuard : (x: any) => any
|
||
>a : A
|
||
|
||
a.propB;
|
||
>a.propB : any
|
||
>a : A
|
||
>propB : any
|
||
}
|
||
|
||
// Type predicate type is not assignable
|
||
declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B);
|
||
>acceptingDifferentSignatureTypeGuardFunction : (p1: (p1: any) => p1 is B) => any
|
||
>p1 : (p1: any) => p1 is B
|
||
>p1 : any
|
||
|
||
acceptingDifferentSignatureTypeGuardFunction(isC);
|
||
>acceptingDifferentSignatureTypeGuardFunction(isC) : any
|
||
>acceptingDifferentSignatureTypeGuardFunction : (p1: (p1: any) => p1 is B) => any
|
||
>isC : (p1: any) => p1 is C
|
||
|
||
// Boolean not assignable to type guard
|
||
var assign1: (p1, p2) => p1 is A;
|
||
>assign1 : (p1: any, p2: any) => p1 is A
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
assign1 = function(p1, p2): boolean {
|
||
>assign1 = function(p1, p2): boolean { return true;} : (p1: any, p2: any) => boolean
|
||
>assign1 : (p1: any, p2: any) => p1 is A
|
||
>function(p1, p2): boolean { return true;} : (p1: any, p2: any) => boolean
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
return true;
|
||
>true : true
|
||
|
||
};
|
||
|
||
// Must have matching parameter index
|
||
var assign2: (p1, p2) => p1 is A;
|
||
>assign2 : (p1: any, p2: any) => p1 is A
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
assign2 = function(p1, p2): p2 is A {
|
||
>assign2 = function(p1, p2): p2 is A { return true;} : (p1: any, p2: any) => p2 is A
|
||
>assign2 : (p1: any, p2: any) => p1 is A
|
||
>function(p1, p2): p2 is A { return true;} : (p1: any, p2: any) => p2 is A
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
return true;
|
||
>true : true
|
||
|
||
};
|
||
|
||
// No matching signature
|
||
var assign3: (p1, p2) => p1 is A;
|
||
>assign3 : (p1: any, p2: any) => p1 is A
|
||
>p1 : any
|
||
>p2 : any
|
||
|
||
assign3 = function(p1, p2, p3): p1 is A {
|
||
>assign3 = function(p1, p2, p3): p1 is A { return true;} : (p1: any, p2: any, p3: any) => p1 is A
|
||
>assign3 : (p1: any, p2: any) => p1 is A
|
||
>function(p1, p2, p3): p1 is A { return true;} : (p1: any, p2: any, p3: any) => p1 is A
|
||
>p1 : any
|
||
>p2 : any
|
||
>p3 : any
|
||
|
||
return true;
|
||
>true : true
|
||
|
||
};
|
||
|
||
// Type predicates in non-return type positions
|
||
var b1: b is A;
|
||
>b1 : b
|
||
>is : any
|
||
>A : any
|
||
|
||
function b2(a: b is A) {};
|
||
>b2 : (a: b, is: any, A: any) => void
|
||
>a : b
|
||
>is : any
|
||
>A : any
|
||
|
||
function b3(): A | b is A {
|
||
>b3 : () => A | b
|
||
>is : any
|
||
>A : typeof A
|
||
|
||
return true;
|
||
>true : true
|
||
|
||
};
|
||
|
||
// Non-compatiable type predicate positions for signature declarations
|
||
class D {
|
||
>D : D
|
||
|
||
constructor(p1: A): p1 is C {
|
||
>p1 : A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
get m1(p1: A): p1 is C {
|
||
>m1 : boolean
|
||
>p1 : A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
set m2(p1: A): p1 is C {
|
||
>m2 : A
|
||
>p1 : A
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
}
|
||
|
||
interface I1 {
|
||
new (p1: A): p1 is C;
|
||
>p1 : A
|
||
}
|
||
|
||
interface I2 {
|
||
[index: number]: p1 is C;
|
||
>index : number
|
||
>is : any
|
||
>C : typeof C
|
||
}
|
||
|
||
// Reference to rest parameter
|
||
function b4(...a): a is A {
|
||
>b4 : (...a: any[]) => a is A
|
||
>a : any[]
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
// Reference to binding pattern
|
||
function b5({a, b, p1}, p2, p3): p1 is A {
|
||
>b5 : ({ a, b, p1 }: { a: any; b: any; p1: any; }, p2: any, p3: any) => p1 is A
|
||
>a : any
|
||
>b : any
|
||
>p1 : any
|
||
>p2 : any
|
||
>p3 : any
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function b6([a, b, p1], p2, p3): p1 is A {
|
||
>b6 : ([a, b, p1]: [any, any, any], p2: any, p3: any) => p1 is A
|
||
>a : any
|
||
>b : any
|
||
>p1 : any
|
||
>p2 : any
|
||
>p3 : any
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||
>b7 : ({ a, b, c: { p1 } }: { a: any; b: any; c: { p1: any; }; }, p2: any, p3: any) => p1 is A
|
||
>a : any
|
||
>b : any
|
||
>c : any
|
||
>p1 : any
|
||
>p2 : any
|
||
>p3 : any
|
||
|
||
return true;
|
||
>true : true
|
||
}
|
||
|
||
// Should not crash the compiler
|
||
var x: A;
|
||
>x : A
|
||
|
||
if (hasMissingParameter()) {
|
||
>hasMissingParameter() : boolean
|
||
>hasMissingParameter : () => x is A
|
||
|
||
x.propA;
|
||
>x.propA : number
|
||
>x : A
|
||
>propA : number
|
||
}
|
||
|
||
// repro #17297
|
||
|
||
type Keys = 'a'|'b'|'c'
|
||
>Keys : Keys
|
||
|
||
type KeySet<T extends Keys> = { [k in T]: true }
|
||
>KeySet : KeySet<T>
|
||
>true : true
|
||
|
||
// expected an error, since Keys doesn't have a 'd'
|
||
declare function hasKey<T extends Keys>(x: KeySet<T>): x is KeySet<T|'d'>;
|
||
>hasKey : <T extends Keys>(x: KeySet<T>) => x is KeySet<T | "d">
|
||
>x : KeySet<T>
|
||
|
||
type Foo = { 'a': string; }
|
||
>Foo : Foo
|
||
>'a' : string
|
||
|
||
type Bar = { 'a': number; }
|
||
>Bar : Bar
|
||
>'a' : number
|
||
|
||
interface NeedsFoo<T extends Foo> {
|
||
foo: T;
|
||
>foo : T
|
||
|
||
isFoo(): this is NeedsFoo<Bar>; // should error
|
||
>isFoo : () => this is NeedsFoo<Bar>
|
||
|
||
};
|
||
|
||
declare var anError: NeedsFoo<Bar>; // error, as expected
|
||
>anError : NeedsFoo<Bar>
|
||
|
||
declare var alsoAnError: NeedsFoo<number>; // also error, as expected
|
||
>alsoAnError : NeedsFoo<number>
|
||
|
||
declare function newError1(x: any): x is NeedsFoo<Bar>; // should error
|
||
>newError1 : (x: any) => x is NeedsFoo<Bar>
|
||
>x : any
|
||
|
||
declare function newError2(x: any): x is NeedsFoo<number>; // should error
|
||
>newError2 : (x: any) => x is NeedsFoo<number>
|
||
>x : any
|
||
|
||
declare function newError3(x: number): x is NeedsFoo<number>; // should error
|
||
>newError3 : (x: number) => x is NeedsFoo<number>
|
||
>x : number
|
||
|