Skip to content

Commit ffb9585

Browse files
Allow this when it appears in this is T positions (#59310)
1 parent 8daac14 commit ffb9585

12 files changed

+140
-156
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40980,10 +40980,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4098040980
checkSourceElement(node.type);
4098140981

4098240982
const { parameterName } = node;
40983-
if (typePredicate.kind === TypePredicateKind.This || typePredicate.kind === TypePredicateKind.AssertsThis) {
40984-
getTypeFromThisTypeNode(parameterName as ThisTypeNode);
40985-
}
40986-
else {
40983+
if (typePredicate.kind !== TypePredicateKind.This && typePredicate.kind !== TypePredicateKind.AssertsThis) {
4098740984
if (typePredicate.parameterIndex >= 0) {
4098840985
if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) {
4098940986
error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);

tests/baselines/reference/declarationEmitThisPredicates02.errors.txt

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/baselines/reference/declarationEmitThisPredicates02.types

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export const obj = {
3333
>this as {} : {}
3434
> : ^^
3535
>this : any
36-
> : ^^^
3736

3837
return dis.a != null && dis.b != null && dis.c != null;
3938
>dis.a != null && dis.b != null && dis.c != null : boolean

tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.types

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export const obj = {
3333
>this as {} : {}
3434
> : ^^
3535
>this : any
36-
> : ^^^
3736

3837
return dis.a != null && dis.b != null && dis.c != null;
3938
>dis.a != null && dis.b != null && dis.c != null : boolean

tests/baselines/reference/mappedTypeWithAsClauseAndLateBoundProperty2.js

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -107,113 +107,3 @@ export declare const thing: {
107107
readonly [Symbol.unscopables]?: boolean;
108108
};
109109
};
110-
111-
112-
//// [DtsFileErrors]
113-
114-
115-
mappedTypeWithAsClauseAndLateBoundProperty2.d.ts(27,118): error TS2526: A 'this' type is available only in a non-static member of a class or interface.
116-
117-
118-
==== mappedTypeWithAsClauseAndLateBoundProperty2.d.ts (1 errors) ====
119-
export declare const thing: {
120-
[x: number]: number;
121-
toString: () => string;
122-
toLocaleString: {
123-
(): string;
124-
(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string;
125-
};
126-
pop: () => number;
127-
push: (...items: number[]) => number;
128-
concat: {
129-
(...items: ConcatArray<number>[]): number[];
130-
(...items: (number | ConcatArray<number>)[]): number[];
131-
};
132-
join: (separator?: string) => string;
133-
reverse: () => number[];
134-
shift: () => number;
135-
slice: (start?: number, end?: number) => number[];
136-
sort: (compareFn?: (a: number, b: number) => number) => number[];
137-
splice: {
138-
(start: number, deleteCount?: number): number[];
139-
(start: number, deleteCount: number, ...items: number[]): number[];
140-
};
141-
unshift: (...items: number[]) => number;
142-
indexOf: (searchElement: number, fromIndex?: number) => number;
143-
lastIndexOf: (searchElement: number, fromIndex?: number) => number;
144-
every: {
145-
<S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[];
146-
~~~~
147-
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
148-
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean;
149-
};
150-
some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean;
151-
forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void;
152-
map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[];
153-
filter: {
154-
<S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[];
155-
(predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[];
156-
};
157-
reduce: {
158-
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
159-
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
160-
<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U;
161-
};
162-
reduceRight: {
163-
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number;
164-
(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number;
165-
<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U;
166-
};
167-
find: {
168-
<S extends number>(predicate: (value: number, index: number, obj: number[]) => value is S, thisArg?: any): S;
169-
(predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number;
170-
};
171-
findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number;
172-
fill: (value: number, start?: number, end?: number) => number[];
173-
copyWithin: (target: number, start: number, end?: number) => number[];
174-
entries: () => BuiltinIterator<[number, number], any, any>;
175-
keys: () => BuiltinIterator<number, BuiltinIteratorReturn>;
176-
values: () => BuiltinIterator<number, any, any>;
177-
includes: (searchElement: number, fromIndex?: number) => boolean;
178-
flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[];
179-
flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[];
180-
[Symbol.iterator]: () => BuiltinIterator<number, any, any>;
181-
readonly [Symbol.unscopables]: {
182-
[x: number]: boolean;
183-
length?: boolean;
184-
toString?: boolean;
185-
toLocaleString?: boolean;
186-
pop?: boolean;
187-
push?: boolean;
188-
concat?: boolean;
189-
join?: boolean;
190-
reverse?: boolean;
191-
shift?: boolean;
192-
slice?: boolean;
193-
sort?: boolean;
194-
splice?: boolean;
195-
unshift?: boolean;
196-
indexOf?: boolean;
197-
lastIndexOf?: boolean;
198-
every?: boolean;
199-
some?: boolean;
200-
forEach?: boolean;
201-
map?: boolean;
202-
filter?: boolean;
203-
reduce?: boolean;
204-
reduceRight?: boolean;
205-
find?: boolean;
206-
findIndex?: boolean;
207-
fill?: boolean;
208-
copyWithin?: boolean;
209-
entries?: boolean;
210-
keys?: boolean;
211-
values?: boolean;
212-
includes?: boolean;
213-
flatMap?: boolean;
214-
flat?: boolean;
215-
[Symbol.iterator]?: boolean;
216-
readonly [Symbol.unscopables]?: boolean;
217-
};
218-
};
219-
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
thisPredicateInObjectLiteral.ts(10,28): error TS2526: A 'this' type is available only in a non-static member of a class or interface.
2+
3+
4+
==== thisPredicateInObjectLiteral.ts (1 errors) ====
5+
// Should be OK
6+
const foo2 = {
7+
isNumber(): this is { b: string } {
8+
return true;
9+
},
10+
};
11+
12+
// Still an error
13+
const foo3 = {
14+
isNumber(x: any): x is this {
15+
~~~~
16+
!!! error TS2526: A 'this' type is available only in a non-static member of a class or interface.
17+
return true;
18+
},
19+
};
20+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/compiler/thisPredicateInObjectLiteral.ts] ////
2+
3+
//// [thisPredicateInObjectLiteral.ts]
4+
// Should be OK
5+
const foo2 = {
6+
isNumber(): this is { b: string } {
7+
return true;
8+
},
9+
};
10+
11+
// Still an error
12+
const foo3 = {
13+
isNumber(x: any): x is this {
14+
return true;
15+
},
16+
};
17+
18+
19+
//// [thisPredicateInObjectLiteral.js]
20+
"use strict";
21+
// Should be OK
22+
var foo2 = {
23+
isNumber: function () {
24+
return true;
25+
},
26+
};
27+
// Still an error
28+
var foo3 = {
29+
isNumber: function (x) {
30+
return true;
31+
},
32+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/compiler/thisPredicateInObjectLiteral.ts] ////
2+
3+
=== thisPredicateInObjectLiteral.ts ===
4+
// Should be OK
5+
const foo2 = {
6+
>foo2 : Symbol(foo2, Decl(thisPredicateInObjectLiteral.ts, 1, 5))
7+
8+
isNumber(): this is { b: string } {
9+
>isNumber : Symbol(isNumber, Decl(thisPredicateInObjectLiteral.ts, 1, 14))
10+
>b : Symbol(b, Decl(thisPredicateInObjectLiteral.ts, 2, 25))
11+
12+
return true;
13+
},
14+
};
15+
16+
// Still an error
17+
const foo3 = {
18+
>foo3 : Symbol(foo3, Decl(thisPredicateInObjectLiteral.ts, 8, 5))
19+
20+
isNumber(x: any): x is this {
21+
>isNumber : Symbol(isNumber, Decl(thisPredicateInObjectLiteral.ts, 8, 14))
22+
>x : Symbol(x, Decl(thisPredicateInObjectLiteral.ts, 9, 13))
23+
>x : Symbol(x, Decl(thisPredicateInObjectLiteral.ts, 9, 13))
24+
25+
return true;
26+
},
27+
};
28+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//// [tests/cases/compiler/thisPredicateInObjectLiteral.ts] ////
2+
3+
=== thisPredicateInObjectLiteral.ts ===
4+
// Should be OK
5+
const foo2 = {
6+
>foo2 : { isNumber(): this is { b: string; }; }
7+
> : ^^^^^^^^^^^^^^ ^^^
8+
>{ isNumber(): this is { b: string } { return true; },} : { isNumber(): this is { b: string; }; }
9+
> : ^^^^^^^^^^^^^^ ^^^
10+
11+
isNumber(): this is { b: string } {
12+
>isNumber : () => this is { b: string; }
13+
> : ^^^^^^
14+
>b : string
15+
> : ^^^^^^
16+
17+
return true;
18+
>true : true
19+
> : ^^^^
20+
21+
},
22+
};
23+
24+
// Still an error
25+
const foo3 = {
26+
>foo3 : { isNumber(x: any): x is this; }
27+
> : ^^^^^^^^^^^ ^^ ^^^ ^^^
28+
>{ isNumber(x: any): x is this { return true; },} : { isNumber(x: any): x is this; }
29+
> : ^^^^^^^^^^^ ^^ ^^^ ^^^
30+
31+
isNumber(x: any): x is this {
32+
>isNumber : (x: any) => x is this
33+
> : ^ ^^ ^^^^^
34+
>x : any
35+
> : ^^^
36+
37+
return true;
38+
>true : true
39+
> : ^^^^
40+
41+
},
42+
};
43+

0 commit comments

Comments
 (0)