Skip to content

Commit 8221170

Browse files
committed
feat: introduct throw type
1 parent 1488f35 commit 8221170

File tree

5 files changed

+38
-5
lines changed

5 files changed

+38
-5
lines changed

src/compiler/checker.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4493,6 +4493,9 @@ namespace ts {
44934493
if (type.flags & TypeFlags.Substitution) {
44944494
return typeToTypeNodeHelper((<SubstitutionType>type).baseType, context);
44954495
}
4496+
if (type.flags & TypeFlags.ThrowType) {
4497+
return typeToTypeNodeHelper(errorType, context);
4498+
}
44964499

44974500
return Debug.fail("Should be unreachable.");
44984501

@@ -13391,6 +13394,9 @@ namespace ts {
1339113394
case SyntaxKind.ReadonlyKeyword:
1339213395
links.resolvedType = getTypeFromTypeNode(node.type);
1339313396
break;
13397+
case SyntaxKind.ThrowKeyword:
13398+
links.resolvedType = createThrowType(getTypeFromTypeNode(node.type));
13399+
break;
1339413400
default:
1339513401
throw Debug.assertNever(node.operator);
1339613402
}
@@ -14461,6 +14467,12 @@ namespace ts {
1446114467
return type;
1446214468
}
1446314469

14470+
function createThrowType(containingType: Type) {
14471+
const type = <ThrowType>createType(TypeFlags.ThrowType);
14472+
type.value = containingType;
14473+
return type;
14474+
}
14475+
1446414476
function getESSymbolLikeTypeForNode(node: Node) {
1446514477
if (isValidESSymbolDeclaration(node)) {
1446614478
const symbol = getSymbolOfNode(node);
@@ -15113,6 +15125,15 @@ namespace ts {
1511315125
return sub;
1511415126
}
1511515127
}
15128+
if (flags & TypeFlags.ThrowType) {
15129+
const innerType = instantiateType((<ThrowType>type).value, mapper);
15130+
let errorMessage = "Unknown";
15131+
if (innerType.flags & TypeFlags.StringLiteral) {
15132+
errorMessage = (<StringLiteralType>innerType).value;
15133+
}
15134+
error(currentNode, Diagnostics.Type_instantiated_results_in_a_throw_type_saying_Colon_0, errorMessage);
15135+
return errorType;
15136+
}
1511615137
return type;
1511715138
}
1511815139

@@ -19312,6 +19333,9 @@ namespace ts {
1931219333
// results for union and intersection types for performance reasons.
1931319334
function couldContainTypeVariables(type: Type): boolean {
1931419335
const objectFlags = getObjectFlags(type);
19336+
if (type.flags & TypeFlags.ThrowType) {
19337+
return couldContainTypeVariables((<ThrowType>type).value);
19338+
}
1931519339
if (objectFlags & ObjectFlags.CouldContainTypeVariablesComputed) {
1931619340
return !!(objectFlags & ObjectFlags.CouldContainTypeVariables);
1931719341
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3020,7 +3020,10 @@
30203020
"category": "Error",
30213021
"code": 2793
30223022
},
3023-
3023+
"Type instantiated results in a throw type saying: {0}": {
3024+
"category": "Error",
3025+
"code": 2794
3026+
},
30243027

30253028
"Import declaration '{0}' is using private name '{1}'.": {
30263029
"category": "Error",

src/compiler/factory/nodeFactory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,7 @@ namespace ts {
19691969
}
19701970

19711971
// @api
1972-
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode {
1972+
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode {
19731973
const node = createBaseNode<TypeOperatorNode>(SyntaxKind.TypeOperator);
19741974
node.operator = operator;
19751975
node.type = parenthesizerRules().parenthesizeMemberOfElementType(type);

src/compiler/parser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3585,7 +3585,7 @@ namespace ts {
35853585
return type;
35863586
}
35873587

3588-
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) {
3588+
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword) {
35893589
const pos = getNodePos();
35903590
parseExpected(operator);
35913591
return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos);
@@ -3615,6 +3615,7 @@ namespace ts {
36153615
case SyntaxKind.KeyOfKeyword:
36163616
case SyntaxKind.UniqueKeyword:
36173617
case SyntaxKind.ReadonlyKeyword:
3618+
case SyntaxKind.ThrowKeyword:
36183619
return parseTypeOperator(operator);
36193620
case SyntaxKind.InferKeyword:
36203621
return parseInferType();

src/compiler/types.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,7 @@ namespace ts {
16131613

16141614
export interface TypeOperatorNode extends TypeNode {
16151615
readonly kind: SyntaxKind.TypeOperator;
1616-
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
1616+
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword;
16171617
readonly type: TypeNode;
16181618
}
16191619

@@ -4873,6 +4873,7 @@ namespace ts {
48734873
Substitution = 1 << 25, // Type parameter substitution
48744874
NonPrimitive = 1 << 26, // intrinsic object type
48754875
TemplateLiteral = 1 << 27, // Template literal type
4876+
ThrowType = 1 << 28, // throw T
48764877

48774878
/* @internal */
48784879
AnyOrUnknown = Any | Unknown,
@@ -5008,6 +5009,10 @@ namespace ts {
50085009
export interface EnumType extends Type {
50095010
}
50105011

5012+
export interface ThrowType extends Type {
5013+
value: Type;
5014+
}
5015+
50115016
export const enum ObjectFlags {
50125017
Class = 1 << 0, // Class
50135018
Interface = 1 << 1, // Interface
@@ -6781,7 +6786,7 @@ namespace ts {
67816786
createParenthesizedType(type: TypeNode): ParenthesizedTypeNode;
67826787
updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
67836788
createThisTypeNode(): ThisTypeNode;
6784-
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
6789+
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode;
67856790
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
67866791
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
67876792
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;

0 commit comments

Comments
 (0)