Skip to content

Throw types #40468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1befac3
feat: introduce throw type
Jack-Works Sep 6, 2020
2a9f067
feat: handle throw type in call expression
Jack-Works Sep 6, 2020
f1286b6
feat: add typeof modifier in template string
Jack-Works Sep 6, 2020
1c1c653
chore: accept baseline
Jack-Works Sep 8, 2020
22c76cf
fix: un-instantiate throw type in return type
Jack-Works Sep 10, 2020
241cc97
fix: throw type parse error at true branch of conditional type
Jack-Works Sep 10, 2020
530c395
feat: add throw type check for identifier
Jack-Works Sep 10, 2020
d69f2b0
fix: lint error
Jack-Works Sep 10, 2020
b5f4fce
feat: able to reference translated diagnostic message
Jack-Works Sep 11, 2020
b39ff3d
feat: support category in throw type
Jack-Works Sep 11, 2020
1950b0f
fix: base case of throw types
Jack-Works Sep 11, 2020
9faf8c4
test: add test case for prevent call expr usage
Jack-Works Sep 11, 2020
daac7e7
test: add test for identifier use case
Jack-Works Sep 11, 2020
7d785eb
feat: improve throw type on return type
Jack-Works Sep 12, 2020
c22687f
feat: improve throw type on argument position
Jack-Works Sep 12, 2020
c21c1b7
feat: add property access check for throw type
Jack-Works Sep 12, 2020
94aa731
fix: infinite loop in dropThrowTypeInConditionalType
Jack-Works Sep 12, 2020
56bfcd7
fix: throw type in fn param, co-assign in cond type
Jack-Works Sep 16, 2020
bd0f330
feat: reduce throw type in intersection
Jack-Works Sep 19, 2020
cdd5cd0
Merge branch 'master' into throwTypes
Jack-Works Sep 22, 2020
cfd61cb
Merge branch 'master' into throwTypes
Jack-Works Nov 12, 2020
800fb0c
chore: accept new baseline
Jack-Works Nov 12, 2020
e391bc4
feat: add intrinsic type
Jack-Works Feb 6, 2021
e5e4c0b
Merge branch 'main' into throwTypes
Jack-Works Feb 6, 2021
14c00cc
chore: update baseline
Jack-Works Feb 6, 2021
2303958
fix: linter
Jack-Works Feb 6, 2021
e138279
Merge branch 'main' into throwTypes
Jack-Works Mar 27, 2021
c2ae402
test: update tests
Jack-Works Mar 27, 2021
27df052
Merge branch 'main' into throwTypes
Jack-Works Jul 26, 2021
4f01135
Merge branch 'main' into throwTypes
Jack-Works Feb 14, 2022
e7684dc
fix: test failed
Jack-Works Feb 14, 2022
361bb7b
Merge branch 'main' into throwTypes
Jack-Works Sep 25, 2022
ea2c58d
fix: lint
Jack-Works Sep 25, 2022
a995c42
fix: test failed
Jack-Works Sep 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 185 additions & 23 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3567,6 +3567,10 @@
"category": "Error",
"code": 2845
},
"Type instantiated results in a throw type saying: {0}": {
"category": "Error",
"code": 2899
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/factory/nodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2171,7 +2171,7 @@ namespace ts {
}

// @api
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode {
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode {
const node = createBaseNode<TypeOperatorNode>(SyntaxKind.TypeOperator);
node.operator = operator;
node.type = operator === SyntaxKind.ReadonlyKeyword ?
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4146,6 +4146,7 @@ namespace ts {
case SyntaxKind.ReadonlyKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UniqueKeyword:
case SyntaxKind.ThrowKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
Expand Down Expand Up @@ -4228,7 +4229,7 @@ namespace ts {
return type;
}

function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) {
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword) {
const pos = getNodePos();
parseExpected(operator);
return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos);
Expand Down Expand Up @@ -4263,6 +4264,7 @@ namespace ts {
case SyntaxKind.KeyOfKeyword:
case SyntaxKind.UniqueKeyword:
case SyntaxKind.ReadonlyKeyword:
case SyntaxKind.ThrowKeyword:
return parseTypeOperator(operator);
case SyntaxKind.InferKeyword:
return parseInferType();
Expand Down
9 changes: 7 additions & 2 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2045,7 +2045,7 @@ namespace ts {

export interface TypeOperatorNode extends TypeNode {
readonly kind: SyntaxKind.TypeOperator;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword;
readonly type: TypeNode;
}

Expand Down Expand Up @@ -5605,6 +5605,7 @@ namespace ts {
NonPrimitive = 1 << 26, // intrinsic object type
TemplateLiteral = 1 << 27, // Template literal type
StringMapping = 1 << 28, // Uppercase/Lowercase type
ThrowType = 1 << 29, // throw T

/* @internal */
AnyOrUnknown = Any | Unknown,
Expand Down Expand Up @@ -5745,6 +5746,10 @@ namespace ts {
export interface EnumType extends Type {
}

export interface ThrowType extends Type {
value: Type;
}

// Types included in TypeFlags.ObjectFlagsType have an objectFlags property. Some ObjectFlags
// are specific to certain types and reuse the same bit position. Those ObjectFlags require a check
// for a certain TypeFlags value to determine their meaning.
Expand Down Expand Up @@ -7812,7 +7817,7 @@ namespace ts {
createParenthesizedType(type: TypeNode): ParenthesizedTypeNode;
updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
createThisTypeNode(): ThisTypeNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode;
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
Expand Down
1 change: 1 addition & 0 deletions src/harness/fourslashInterfaceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,7 @@ namespace FourSlashInterface {
typeEntry("Lowercase"),
typeEntry("Capitalize"),
typeEntry("Uncapitalize"),
typeEntry("TypeToString"),
interfaceEntry("ThisType"),
varEntry("ArrayBuffer"),
interfaceEntry("ArrayBufferTypes"),
Expand Down
5 changes: 5 additions & 0 deletions src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,11 @@ type Capitalize<S extends string> = intrinsic;
*/
type Uncapitalize<S extends string> = intrinsic;

/**
* Get a string representation of a type
*/
type TypeToString<T> = intrinsic;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, NameOf<T> might be a better name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That issue requires a runtime behavior but this one is only type-level. I don't know if it is a good idea to use NameOf


/**
* Marker for contextual 'this' type
*/
Expand Down
8 changes: 6 additions & 2 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ declare namespace ts {
}
export interface TypeOperatorNode extends TypeNode {
readonly kind: SyntaxKind.TypeOperator;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword;
readonly type: TypeNode;
}
export interface IndexedAccessTypeNode extends TypeNode {
Expand Down Expand Up @@ -2665,6 +2665,7 @@ declare namespace ts {
NonPrimitive = 67108864,
TemplateLiteral = 134217728,
StringMapping = 268435456,
ThrowType = 536870912,
Literal = 2944,
Unit = 109440,
StringOrNumberLiteral = 384,
Expand Down Expand Up @@ -2713,6 +2714,9 @@ declare namespace ts {
}
export interface EnumType extends Type {
}
export interface ThrowType extends Type {
value: Type;
}
export enum ObjectFlags {
Class = 1,
Interface = 2,
Expand Down Expand Up @@ -3518,7 +3522,7 @@ declare namespace ts {
createParenthesizedType(type: TypeNode): ParenthesizedTypeNode;
updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
createThisTypeNode(): ThisTypeNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode;
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
Expand Down
8 changes: 6 additions & 2 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ declare namespace ts {
}
export interface TypeOperatorNode extends TypeNode {
readonly kind: SyntaxKind.TypeOperator;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
readonly operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword;
readonly type: TypeNode;
}
export interface IndexedAccessTypeNode extends TypeNode {
Expand Down Expand Up @@ -2665,6 +2665,7 @@ declare namespace ts {
NonPrimitive = 67108864,
TemplateLiteral = 134217728,
StringMapping = 268435456,
ThrowType = 536870912,
Literal = 2944,
Unit = 109440,
StringOrNumberLiteral = 384,
Expand Down Expand Up @@ -2713,6 +2714,9 @@ declare namespace ts {
}
export interface EnumType extends Type {
}
export interface ThrowType extends Type {
value: Type;
}
export enum ObjectFlags {
Class = 1,
Interface = 2,
Expand Down Expand Up @@ -3518,7 +3522,7 @@ declare namespace ts {
createParenthesizedType(type: TypeNode): ParenthesizedTypeNode;
updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
createThisTypeNode(): ThisTypeNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.ThrowKeyword, type: TypeNode): TypeOperatorNode;
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
Expand Down
33 changes: 33 additions & 0 deletions tests/baselines/reference/throwType_function_parameter.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
tests/cases/compiler/throwType_function_parameter.ts(4,24): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
tests/cases/compiler/throwType_function_parameter.ts(4,24): error TS2899: Type instantiated results in a throw type saying:
No zero
tests/cases/compiler/throwType_function_parameter.ts(13,4): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
tests/cases/compiler/throwType_function_parameter.ts(13,4): error TS2899: Type instantiated results in a throw type saying:
"found ""str""


==== tests/cases/compiler/throwType_function_parameter.ts (4 errors) ====
function checkParameterPosition<T extends number>(y: T extends 1234 ? throw 'No zero' : T) {
y.toExponential()
}
checkParameterPosition(1234)
~~~~
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'.
~~~~
!!! error TS2899: Type instantiated results in a throw type saying:
!!! error TS2899: No zero
checkParameterPosition(12345678)

type MustNumber<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
type MustNumber2<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
function f2<T>(a: MustNumber<T>, b: MustNumber2<T>) {
a = b
}

f2('str', {})
~~~~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
~~~~~
!!! error TS2899: Type instantiated results in a throw type saying:
!!! error TS2899: "found ""str""

26 changes: 26 additions & 0 deletions tests/baselines/reference/throwType_function_parameter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [throwType_function_parameter.ts]
function checkParameterPosition<T extends number>(y: T extends 1234 ? throw 'No zero' : T) {
y.toExponential()
}
checkParameterPosition(1234)
checkParameterPosition(12345678)

type MustNumber<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
type MustNumber2<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
function f2<T>(a: MustNumber<T>, b: MustNumber2<T>) {
a = b
}

f2('str', {})


//// [throwType_function_parameter.js]
function checkParameterPosition(y) {
y.toExponential();
}
checkParameterPosition(1234);
checkParameterPosition(12345678);
function f2(a, b) {
a = b;
}
f2('str', {});
53 changes: 53 additions & 0 deletions tests/baselines/reference/throwType_function_parameter.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
=== tests/cases/compiler/throwType_function_parameter.ts ===
function checkParameterPosition<T extends number>(y: T extends 1234 ? throw 'No zero' : T) {
>checkParameterPosition : Symbol(checkParameterPosition, Decl(throwType_function_parameter.ts, 0, 0))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 0, 32))
>y : Symbol(y, Decl(throwType_function_parameter.ts, 0, 50))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 0, 32))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 0, 32))

y.toExponential()
>y.toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
>y : Symbol(y, Decl(throwType_function_parameter.ts, 0, 50))
>toExponential : Symbol(Number.toExponential, Decl(lib.es5.d.ts, --, --))
}
checkParameterPosition(1234)
>checkParameterPosition : Symbol(checkParameterPosition, Decl(throwType_function_parameter.ts, 0, 0))

checkParameterPosition(12345678)
>checkParameterPosition : Symbol(checkParameterPosition, Decl(throwType_function_parameter.ts, 0, 0))

type MustNumber<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
>MustNumber : Symbol(MustNumber, Decl(throwType_function_parameter.ts, 4, 32))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 6, 16))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 6, 16))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 6, 16))
>TypeToString : Symbol(TypeToString, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 6, 16))

type MustNumber2<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
>MustNumber2 : Symbol(MustNumber2, Decl(throwType_function_parameter.ts, 6, 79))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 7, 17))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 7, 17))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 7, 17))
>TypeToString : Symbol(TypeToString, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 7, 17))

function f2<T>(a: MustNumber<T>, b: MustNumber2<T>) {
>f2 : Symbol(f2, Decl(throwType_function_parameter.ts, 7, 80))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 8, 12))
>a : Symbol(a, Decl(throwType_function_parameter.ts, 8, 15))
>MustNumber : Symbol(MustNumber, Decl(throwType_function_parameter.ts, 4, 32))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 8, 12))
>b : Symbol(b, Decl(throwType_function_parameter.ts, 8, 32))
>MustNumber2 : Symbol(MustNumber2, Decl(throwType_function_parameter.ts, 6, 79))
>T : Symbol(T, Decl(throwType_function_parameter.ts, 8, 12))

a = b
>a : Symbol(a, Decl(throwType_function_parameter.ts, 8, 15))
>b : Symbol(b, Decl(throwType_function_parameter.ts, 8, 32))
}

f2('str', {})
>f2 : Symbol(f2, Decl(throwType_function_parameter.ts, 7, 80))

44 changes: 44 additions & 0 deletions tests/baselines/reference/throwType_function_parameter.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
=== tests/cases/compiler/throwType_function_parameter.ts ===
function checkParameterPosition<T extends number>(y: T extends 1234 ? throw 'No zero' : T) {
>checkParameterPosition : <T extends number>(y: T extends 1234 ? throw 'No zero' : T) => void
>y : T extends 1234 ? never : T

y.toExponential()
>y.toExponential() : string
>y.toExponential : (fractionDigits?: number) => string
>y : T extends 1234 ? never : T
>toExponential : (fractionDigits?: number) => string
}
checkParameterPosition(1234)
>checkParameterPosition(1234) : void
>checkParameterPosition : <T extends number>(y: T extends 1234 ? never : T) => void
>1234 : 1234

checkParameterPosition(12345678)
>checkParameterPosition(12345678) : void
>checkParameterPosition : <T extends number>(y: T extends 1234 ? never : T) => void
>12345678 : 12345678

type MustNumber<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
>MustNumber : MustNumber<T>

type MustNumber2<T> = T extends number ? T : throw `"found "${TypeToString<T>}"`
>MustNumber2 : MustNumber2<T>

function f2<T>(a: MustNumber<T>, b: MustNumber2<T>) {
>f2 : <T>(a: MustNumber<T>, b: MustNumber2<T>) => void
>a : MustNumber<T>
>b : MustNumber2<T>

a = b
>a = b : MustNumber2<T>
>a : MustNumber<T>
>b : MustNumber2<T>
}

f2('str', {})
>f2('str', {}) : void
>f2 : <T>(a: MustNumber<T>, b: MustNumber2<T>) => void
>'str' : "str"
>{} : {}

24 changes: 24 additions & 0 deletions tests/baselines/reference/throwType_function_return.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
tests/cases/compiler/throwType_function_return.ts(5,1): error TS2899: Type instantiated results in a throw type saying:
Cannot divided by 0
tests/cases/compiler/throwType_function_return.ts(10,1): error TS2899: Type instantiated results in a throw type saying:
Wrong


==== tests/cases/compiler/throwType_function_return.ts (2 errors) ====
function checkedDivide<T extends number>(x: T): T extends 0 ? throw 'Cannot divided by 0' : number {
if (x === 0) throw new Error('')
return 5 / x
}
checkedDivide(0)
~~~~~~~~~~~~~~~~
!!! error TS2899: Type instantiated results in a throw type saying:
!!! error TS2899: Cannot divided by 0
checkedDivide(1)

const theAnswerToEverything = <T>(x: T): T extends 42 ? T : throw "Wrong" => x
theAnswerToEverything(42 as const)
theAnswerToEverything('')
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2899: Type instantiated results in a throw type saying:
!!! error TS2899: Wrong

24 changes: 24 additions & 0 deletions tests/baselines/reference/throwType_function_return.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [throwType_function_return.ts]
function checkedDivide<T extends number>(x: T): T extends 0 ? throw 'Cannot divided by 0' : number {
if (x === 0) throw new Error('')
return 5 / x
}
checkedDivide(0)
checkedDivide(1)

const theAnswerToEverything = <T>(x: T): T extends 42 ? T : throw "Wrong" => x
theAnswerToEverything(42 as const)
theAnswerToEverything('')


//// [throwType_function_return.js]
function checkedDivide(x) {
if (x === 0)
throw new Error('');
return 5 / x;
}
checkedDivide(0);
checkedDivide(1);
var theAnswerToEverything = function (x) { return x; };
theAnswerToEverything(42);
theAnswerToEverything('');
Loading