Skip to content

Commit 5a76a1d

Browse files
Merge pull request #6744 from Microsoft/removePredicateTypiness
Remove notion of predicates as types, move predicates back to signatures
2 parents e7899cf + 74b1e3f commit 5a76a1d

File tree

58 files changed

+1114
-926
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1114
-926
lines changed

src/compiler/checker.ts

Lines changed: 122 additions & 135 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,10 @@
715715
"category": "Error",
716716
"code": 1227
717717
},
718+
"A type predicate is only allowed in return type position for functions and methods.": {
719+
"category": "Error",
720+
"code": 1228
721+
},
718722
"A type predicate cannot reference a rest parameter.": {
719723
"category": "Error",
720724
"code": 1229

src/compiler/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,7 +1940,7 @@ namespace ts {
19401940
return finishNode(node);
19411941
}
19421942

1943-
function parseTypePredicate(lhs: Identifier | ThisTypeNode): TypePredicateNode {
1943+
function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode {
19441944
nextToken();
19451945
const node = createNode(SyntaxKind.TypePredicate, lhs.pos) as TypePredicateNode;
19461946
node.parameterName = lhs;
@@ -2399,7 +2399,7 @@ namespace ts {
23992399
case SyntaxKind.ThisKeyword: {
24002400
const thisKeyword = parseThisTypeNode();
24012401
if (token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) {
2402-
return parseTypePredicate(thisKeyword);
2402+
return parseThisTypePredicate(thisKeyword);
24032403
}
24042404
else {
24052405
return thisKeyword;

src/compiler/types.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,8 @@ namespace ts {
17771777
buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void;
17781778
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
17791779
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
1780-
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
1780+
buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
1781+
buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
17811782
buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
17821783
buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
17831784
buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
@@ -1842,22 +1843,24 @@ namespace ts {
18421843
Identifier
18431844
}
18441845

1845-
export interface TypePredicate {
1846+
export interface TypePredicateBase {
18461847
kind: TypePredicateKind;
18471848
type: Type;
18481849
}
18491850

18501851
// @kind (TypePredicateKind.This)
1851-
export interface ThisTypePredicate extends TypePredicate {
1852+
export interface ThisTypePredicate extends TypePredicateBase {
18521853
_thisTypePredicateBrand: any;
18531854
}
18541855

18551856
// @kind (TypePredicateKind.Identifier)
1856-
export interface IdentifierTypePredicate extends TypePredicate {
1857+
export interface IdentifierTypePredicate extends TypePredicateBase {
18571858
parameterName: string;
18581859
parameterIndex: number;
18591860
}
18601861

1862+
export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate;
1863+
18611864
/* @internal */
18621865
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
18631866

@@ -2125,7 +2128,6 @@ namespace ts {
21252128
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
21262129
ThisType = 0x02000000, // This type
21272130
ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
2128-
PredicateType = 0x08000000, // Predicate types are also Boolean types, but should not be considered Intrinsics - there's no way to capture this with flags
21292131

21302132
/* @internal */
21312133
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
@@ -2137,7 +2139,7 @@ namespace ts {
21372139
UnionOrIntersection = Union | Intersection,
21382140
StructuredType = ObjectType | Union | Intersection,
21392141
/* @internal */
2140-
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral | PredicateType,
2142+
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral,
21412143
/* @internal */
21422144
PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType
21432145
}
@@ -2158,11 +2160,6 @@ namespace ts {
21582160
intrinsicName: string; // Name of intrinsic type
21592161
}
21602162

2161-
// Predicate types (TypeFlags.Predicate)
2162-
export interface PredicateType extends Type {
2163-
predicate: ThisTypePredicate | IdentifierTypePredicate;
2164-
}
2165-
21662163
// String literal types (TypeFlags.StringLiteral)
21672164
export interface StringLiteralType extends Type {
21682165
text: string; // Text of string literal
@@ -2297,6 +2294,8 @@ namespace ts {
22972294
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
22982295
/* @internal */
22992296
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
2297+
/* @internal */
2298+
typePredicate?: TypePredicate;
23002299
}
23012300

23022301
export const enum IndexKind {

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,10 @@ namespace ts {
746746
return predicate && predicate.kind === TypePredicateKind.Identifier;
747747
}
748748

749+
export function isThisTypePredicate(predicate: TypePredicate): predicate is ThisTypePredicate {
750+
return predicate && predicate.kind === TypePredicateKind.This;
751+
}
752+
749753
export function getContainingFunction(node: Node): FunctionLikeDeclaration {
750754
while (true) {
751755
node = node.parent;

tests/baselines/reference/arrayBufferIsViewNarrowsType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var obj: Object;
44
>Object : Object
55

66
if (ArrayBuffer.isView(obj)) {
7-
>ArrayBuffer.isView(obj) : arg is ArrayBufferView
7+
>ArrayBuffer.isView(obj) : boolean
88
>ArrayBuffer.isView : (arg: any) => arg is ArrayBufferView
99
>ArrayBuffer : ArrayBufferConstructor
1010
>isView : (arg: any) => arg is ArrayBufferView
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [declarationEmitIdentifierPredicates01.ts]
2+
3+
export function f(x: any): x is number {
4+
return typeof x === "number";
5+
}
6+
7+
//// [declarationEmitIdentifierPredicates01.js]
8+
"use strict";
9+
function f(x) {
10+
return typeof x === "number";
11+
}
12+
exports.f = f;
13+
14+
15+
//// [declarationEmitIdentifierPredicates01.d.ts]
16+
export declare function f(x: any): x is number;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts ===
2+
3+
export function f(x: any): x is number {
4+
>f : Symbol(f, Decl(declarationEmitIdentifierPredicates01.ts, 0, 0))
5+
>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18))
6+
>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18))
7+
8+
return typeof x === "number";
9+
>x : Symbol(x, Decl(declarationEmitIdentifierPredicates01.ts, 1, 18))
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicates01.ts ===
2+
3+
export function f(x: any): x is number {
4+
>f : (x: any) => x is number
5+
>x : any
6+
>x : any
7+
8+
return typeof x === "number";
9+
>typeof x === "number" : boolean
10+
>typeof x : string
11+
>x : any
12+
>"number" : string
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts(6,33): error TS4060: Return type of exported function has or is using private name 'I'.
2+
3+
4+
==== tests/cases/conformance/declarationEmit/typePredicates/declarationEmitIdentifierPredicatesWithPrivateName01.ts (1 errors) ====
5+
6+
interface I {
7+
a: number;
8+
}
9+
10+
export function f(x: any): x is I {
11+
~
12+
!!! error TS4060: Return type of exported function has or is using private name 'I'.
13+
return typeof x.a === "number";
14+
}

0 commit comments

Comments
 (0)