mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
check return type of this type predicates (#57341)
This commit is contained in:
parent
13e64740c9
commit
f608fc0a10
@ -736,6 +736,7 @@ import {
|
||||
isThisInTypeQuery,
|
||||
isThisProperty,
|
||||
isThisTypeParameter,
|
||||
isThisTypePredicate,
|
||||
isTransientSymbol,
|
||||
isTupleTypeNode,
|
||||
isTypeAlias,
|
||||
@ -21217,7 +21218,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (sourceTypePredicate) {
|
||||
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes);
|
||||
}
|
||||
else if (isIdentifierTypePredicate(targetTypePredicate)) {
|
||||
else if (isIdentifierTypePredicate(targetTypePredicate) || isThisTypePredicate(targetTypePredicate)) {
|
||||
if (reportErrors) {
|
||||
errorReporter!(Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
|
||||
}
|
||||
|
||||
@ -591,7 +591,7 @@ export class LineNode implements LineCollection {
|
||||
if (children.length) this.updateCounts();
|
||||
}
|
||||
|
||||
isLeaf() {
|
||||
isLeaf(): this is LineLeaf {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -839,7 +839,7 @@ export class LineLeaf implements LineCollection {
|
||||
constructor(public text: string) {
|
||||
}
|
||||
|
||||
isLeaf() {
|
||||
isLeaf(): this is LineLeaf {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
43
tests/baselines/reference/implementArrayInterface.errors.txt
Normal file
43
tests/baselines/reference/implementArrayInterface.errors.txt
Normal file
@ -0,0 +1,43 @@
|
||||
implementArrayInterface.ts(19,5): error TS2416: Property 'every' in type 'MyArray<T>' is not assignable to the same property in base type 'T[]'.
|
||||
Type '(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any) => boolean' is not assignable to type '{ <S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; }'.
|
||||
Signature '(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean' must be a type predicate.
|
||||
|
||||
|
||||
==== implementArrayInterface.ts (1 errors) ====
|
||||
declare class MyArray<T> implements Array<T> {
|
||||
toString(): string;
|
||||
toLocaleString(): string;
|
||||
concat<U extends T[]>(...items: U[]): T[];
|
||||
concat(...items: T[]): T[];
|
||||
join(separator?: string): string;
|
||||
pop(): T;
|
||||
push(...items: T[]): number;
|
||||
reverse(): T[];
|
||||
shift(): T;
|
||||
slice(start?: number, end?: number): T[];
|
||||
sort(compareFn?: (a: T, b: T) => number): this;
|
||||
splice(start: number): T[];
|
||||
splice(start: number, deleteCount: number, ...items: T[]): T[];
|
||||
unshift(...items: T[]): number;
|
||||
|
||||
indexOf(searchElement: T, fromIndex?: number): number;
|
||||
lastIndexOf(searchElement: T, fromIndex?: number): number;
|
||||
every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
|
||||
~~~~~
|
||||
!!! error TS2416: Property 'every' in type 'MyArray<T>' is not assignable to the same property in base type 'T[]'.
|
||||
!!! error TS2416: Type '(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any) => boolean' is not assignable to type '{ <S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; }'.
|
||||
!!! error TS2416: Signature '(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean' must be a type predicate.
|
||||
some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
|
||||
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
|
||||
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
|
||||
filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
|
||||
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
|
||||
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
|
||||
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
|
||||
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
|
||||
|
||||
length: number;
|
||||
|
||||
[n: number]: T;
|
||||
}
|
||||
|
||||
@ -117,6 +117,7 @@ declare class MyArray<T> implements Array<T> {
|
||||
>array : T[]
|
||||
> : ^^^
|
||||
>thisArg : any
|
||||
> : ^^^
|
||||
|
||||
some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
|
||||
>some : (callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any) => boolean
|
||||
@ -130,6 +131,7 @@ declare class MyArray<T> implements Array<T> {
|
||||
>array : T[]
|
||||
> : ^^^
|
||||
>thisArg : any
|
||||
> : ^^^
|
||||
|
||||
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
|
||||
>forEach : (callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any) => void
|
||||
@ -143,6 +145,7 @@ declare class MyArray<T> implements Array<T> {
|
||||
>array : T[]
|
||||
> : ^^^
|
||||
>thisArg : any
|
||||
> : ^^^
|
||||
|
||||
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
|
||||
>map : <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]
|
||||
@ -156,6 +159,7 @@ declare class MyArray<T> implements Array<T> {
|
||||
>array : T[]
|
||||
> : ^^^
|
||||
>thisArg : any
|
||||
> : ^^^
|
||||
|
||||
filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
|
||||
>filter : (callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any) => T[]
|
||||
@ -169,6 +173,7 @@ declare class MyArray<T> implements Array<T> {
|
||||
>array : T[]
|
||||
> : ^^^
|
||||
>thisArg : any
|
||||
> : ^^^
|
||||
|
||||
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
|
||||
>reduce : { (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; <U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
|
||||
|
||||
91
tests/baselines/reference/typePredicateInherit.errors.txt
Normal file
91
tests/baselines/reference/typePredicateInherit.errors.txt
Normal file
@ -0,0 +1,91 @@
|
||||
typePredicateInherit.ts(11,3): error TS2416: Property 'method1' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
Type '() => void' is not assignable to type '() => this is { a: 1; }'.
|
||||
Signature '(): void' must be a type predicate.
|
||||
typePredicateInherit.ts(13,3): error TS2416: Property 'method2' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
Type '() => void' is not assignable to type '() => boolean'.
|
||||
Type 'void' is not assignable to type 'boolean'.
|
||||
typePredicateInherit.ts(15,3): error TS2416: Property 'method3' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
Type '() => boolean' is not assignable to type '() => this is { a: 1; }'.
|
||||
Signature '(): boolean' must be a type predicate.
|
||||
typePredicateInherit.ts(41,3): error TS2416: Property 'method1' in type 'D' is not assignable to the same property in base type 'C'.
|
||||
Type '() => void' is not assignable to type '() => this is { a: 1; }'.
|
||||
Signature '(): void' must be a type predicate.
|
||||
typePredicateInherit.ts(50,3): error TS2416: Property 'method3' in type 'D' is not assignable to the same property in base type 'C'.
|
||||
Type '() => boolean' is not assignable to type '() => this is { a: 1; }'.
|
||||
Signature '(): boolean' must be a type predicate.
|
||||
|
||||
|
||||
==== typePredicateInherit.ts (5 errors) ====
|
||||
interface A {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
}
|
||||
method2(): boolean;
|
||||
method3(): this is {
|
||||
a: 1
|
||||
};
|
||||
}
|
||||
class B implements A {
|
||||
method1() { } // should error
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'method1' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
!!! error TS2416: Type '() => void' is not assignable to type '() => this is { a: 1; }'.
|
||||
!!! error TS2416: Signature '(): void' must be a type predicate.
|
||||
|
||||
method2() { } // should error
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'method2' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
!!! error TS2416: Type '() => void' is not assignable to type '() => boolean'.
|
||||
!!! error TS2416: Type 'void' is not assignable to type 'boolean'.
|
||||
|
||||
method3() { // should error
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'method3' in type 'B' is not assignable to the same property in base type 'A'.
|
||||
!!! error TS2416: Type '() => boolean' is not assignable to type '() => this is { a: 1; }'.
|
||||
!!! error TS2416: Signature '(): boolean' must be a type predicate.
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method2(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
method1(): void { // should error
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'method1' in type 'D' is not assignable to the same property in base type 'C'.
|
||||
!!! error TS2416: Type '() => void' is not assignable to type '() => this is { a: 1; }'.
|
||||
!!! error TS2416: Signature '(): void' must be a type predicate.
|
||||
}
|
||||
|
||||
method2(): this is { // should ok
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): boolean { // should error
|
||||
~~~~~~~
|
||||
!!! error TS2416: Property 'method3' in type 'D' is not assignable to the same property in base type 'C'.
|
||||
!!! error TS2416: Type '() => boolean' is not assignable to type '() => this is { a: 1; }'.
|
||||
!!! error TS2416: Signature '(): boolean' must be a type predicate.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
112
tests/baselines/reference/typePredicateInherit.js
Normal file
112
tests/baselines/reference/typePredicateInherit.js
Normal file
@ -0,0 +1,112 @@
|
||||
//// [tests/cases/compiler/typePredicateInherit.ts] ////
|
||||
|
||||
//// [typePredicateInherit.ts]
|
||||
interface A {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
}
|
||||
method2(): boolean;
|
||||
method3(): this is {
|
||||
a: 1
|
||||
};
|
||||
}
|
||||
class B implements A {
|
||||
method1() { } // should error
|
||||
|
||||
method2() { } // should error
|
||||
|
||||
method3() { // should error
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method2(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
method1(): void { // should error
|
||||
}
|
||||
|
||||
method2(): this is { // should ok
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): boolean { // should error
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//// [typePredicateInherit.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var B = /** @class */ (function () {
|
||||
function B() {
|
||||
}
|
||||
B.prototype.method1 = function () { }; // should error
|
||||
B.prototype.method2 = function () { }; // should error
|
||||
B.prototype.method3 = function () {
|
||||
return true;
|
||||
};
|
||||
return B;
|
||||
}());
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.method1 = function () {
|
||||
return true;
|
||||
};
|
||||
C.prototype.method2 = function () {
|
||||
return true;
|
||||
};
|
||||
C.prototype.method3 = function () {
|
||||
return true;
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
var D = /** @class */ (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
D.prototype.method1 = function () {
|
||||
};
|
||||
D.prototype.method2 = function () {
|
||||
return true;
|
||||
};
|
||||
D.prototype.method3 = function () {
|
||||
return true;
|
||||
};
|
||||
return D;
|
||||
}(C));
|
||||
98
tests/baselines/reference/typePredicateInherit.symbols
Normal file
98
tests/baselines/reference/typePredicateInherit.symbols
Normal file
@ -0,0 +1,98 @@
|
||||
//// [tests/cases/compiler/typePredicateInherit.ts] ////
|
||||
|
||||
=== typePredicateInherit.ts ===
|
||||
interface A {
|
||||
>A : Symbol(A, Decl(typePredicateInherit.ts, 0, 0))
|
||||
|
||||
method1(): this is {
|
||||
>method1 : Symbol(A.method1, Decl(typePredicateInherit.ts, 0, 13))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 1, 22))
|
||||
}
|
||||
method2(): boolean;
|
||||
>method2 : Symbol(A.method2, Decl(typePredicateInherit.ts, 3, 3))
|
||||
|
||||
method3(): this is {
|
||||
>method3 : Symbol(A.method3, Decl(typePredicateInherit.ts, 4, 21))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 5, 22))
|
||||
|
||||
};
|
||||
}
|
||||
class B implements A {
|
||||
>B : Symbol(B, Decl(typePredicateInherit.ts, 8, 1))
|
||||
>A : Symbol(A, Decl(typePredicateInherit.ts, 0, 0))
|
||||
|
||||
method1() { } // should error
|
||||
>method1 : Symbol(B.method1, Decl(typePredicateInherit.ts, 9, 22))
|
||||
|
||||
method2() { } // should error
|
||||
>method2 : Symbol(B.method2, Decl(typePredicateInherit.ts, 10, 15))
|
||||
|
||||
method3() { // should error
|
||||
>method3 : Symbol(B.method3, Decl(typePredicateInherit.ts, 12, 15))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(typePredicateInherit.ts, 17, 1))
|
||||
|
||||
method1(): this is {
|
||||
>method1 : Symbol(C.method1, Decl(typePredicateInherit.ts, 19, 9))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 20, 22))
|
||||
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method2(): this is {
|
||||
>method2 : Symbol(C.method2, Decl(typePredicateInherit.ts, 24, 3))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 26, 22))
|
||||
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): this is {
|
||||
>method3 : Symbol(C.method3, Decl(typePredicateInherit.ts, 30, 3))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 32, 22))
|
||||
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
>D : Symbol(D, Decl(typePredicateInherit.ts, 37, 1))
|
||||
>C : Symbol(C, Decl(typePredicateInherit.ts, 17, 1))
|
||||
|
||||
method1(): void { // should error
|
||||
>method1 : Symbol(D.method1, Decl(typePredicateInherit.ts, 39, 19))
|
||||
}
|
||||
|
||||
method2(): this is { // should ok
|
||||
>method2 : Symbol(D.method2, Decl(typePredicateInherit.ts, 41, 3))
|
||||
|
||||
a: 1
|
||||
>a : Symbol(a, Decl(typePredicateInherit.ts, 43, 22))
|
||||
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): boolean { // should error
|
||||
>method3 : Symbol(D.method3, Decl(typePredicateInherit.ts, 47, 3))
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
129
tests/baselines/reference/typePredicateInherit.types
Normal file
129
tests/baselines/reference/typePredicateInherit.types
Normal file
@ -0,0 +1,129 @@
|
||||
//// [tests/cases/compiler/typePredicateInherit.ts] ////
|
||||
|
||||
=== typePredicateInherit.ts ===
|
||||
interface A {
|
||||
method1(): this is {
|
||||
>method1 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
}
|
||||
method2(): boolean;
|
||||
>method2 : () => boolean
|
||||
> : ^^^^^^
|
||||
|
||||
method3(): this is {
|
||||
>method3 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
|
||||
};
|
||||
}
|
||||
class B implements A {
|
||||
>B : B
|
||||
> : ^
|
||||
|
||||
method1() { } // should error
|
||||
>method1 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
method2() { } // should error
|
||||
>method2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
method3() { // should error
|
||||
>method3 : () => boolean
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
return true
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
> : ^
|
||||
|
||||
method1(): this is {
|
||||
>method1 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
|
||||
} {
|
||||
return true;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
|
||||
method2(): this is {
|
||||
>method2 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
|
||||
} {
|
||||
return true;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
|
||||
method3(): this is {
|
||||
>method3 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
|
||||
} {
|
||||
return true;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
>D : D
|
||||
> : ^
|
||||
>C : C
|
||||
> : ^
|
||||
|
||||
method1(): void { // should error
|
||||
>method1 : () => void
|
||||
> : ^^^^^^
|
||||
}
|
||||
|
||||
method2(): this is { // should ok
|
||||
>method2 : () => this is { a: 1; }
|
||||
> : ^^^^^^
|
||||
|
||||
a: 1
|
||||
>a : 1
|
||||
> : ^
|
||||
|
||||
} {
|
||||
return true;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
|
||||
method3(): boolean { // should error
|
||||
>method3 : () => boolean
|
||||
> : ^^^^^^
|
||||
|
||||
return true;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
}
|
||||
}
|
||||
53
tests/cases/compiler/typePredicateInherit.ts
Normal file
53
tests/cases/compiler/typePredicateInherit.ts
Normal file
@ -0,0 +1,53 @@
|
||||
interface A {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
}
|
||||
method2(): boolean;
|
||||
method3(): this is {
|
||||
a: 1
|
||||
};
|
||||
}
|
||||
class B implements A {
|
||||
method1() { } // should error
|
||||
|
||||
method2() { } // should error
|
||||
|
||||
method3() { // should error
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
method1(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method2(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): this is {
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
method1(): void { // should error
|
||||
}
|
||||
|
||||
method2(): this is { // should ok
|
||||
a: 1
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
method3(): boolean { // should error
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user