This is a fork of Microsoft's TypeScript that adds support for throws clauses in function signatures, enabling explicit exception type declarations and compile-time validation of error handling.
You can read not-to-serious article about this here: Fork Typescript: You Can Just Do Things
- Explicit exception declarations in function signatures
- Compile-time validation that thrown exceptions match the declared throws clause
- Support for complex types including unions, conditionals, and generics
- Type inference for exception types in function bodies
- IntelliSense integration for better developer experience
// Declare that a function can throw specific error types
function parseNumber(input: string): number throws TypeError, RangeError {
if (typeof input !== 'string') {
throw new TypeError('Input must be a string'); // ✅ Valid - TypeError is declared
}
const num = parseInt(input);
if (isNaN(num)) {
throw new RangeError('Invalid number format'); // ✅ Valid - RangeError is declared
}
return num;
}
// Or let TypeScript infer the throws clause from the function body
function parseNumber(input: string) /* throws TypeError, RangeError */ {
if (typeof input !== 'string') {
throw new TypeError('Input must be a string'); // Inferred: TypeError
}
const num = parseInt(input);
if (isNaN(num)) {
throw new RangeError('Invalid number format'); // Inferred: RangeError
}
return num;
}
// and when you call it, TypeScript will check if the function throws the correct error types
function test() { // ❌ Error: Function does not declare throws
parseNumber('123');
}
function test2() throws { // ✅ Valid - no error, pass through any exceptions
parseNumber('123');
}
// Empty throws clause allows rethrowing any caught exceptions
function safeOperation<T>(fn: () => T): T throws {
try {
return fn();
} catch (error) {
// Log error and rethrow
console.error('Operation failed:', error);
throw error; // ✅ Valid - empty throws clause allows rethrowing
}
}
// Multiple exception types using union syntax
function processData(data: unknown): string throws TypeError | ValidationError {
if (typeof data !== 'object') {
throw new TypeError('Data must be an object'); // ✅ Valid
}
if (!isValid(data)) {
throw new ValidationError('Invalid data format'); // ✅ Valid
}
return JSON.stringify(data);
}
// Conditional exception types based on generic parameters
function convert<T extends string | number>(
value: T
): string throws T extends string ? TypeError : RangeError {
if (typeof value === 'string') {
if (value.length === 0) {
throw new TypeError('Empty string not allowed'); // ✅ Valid when T extends string
}
return value;
} else {
if (value < 0) {
throw new RangeError('Negative numbers not allowed'); // ✅ Valid when T extends number
}
return value.toString();
}
}
interface DataProcessor {
// Method signatures can include throws clauses
process(data: string): ProcessedData throws ValidationError;
// Optional throws clause with multiple types
validate?(input: unknown): boolean throws TypeError, ValidationError;
}
class MyProcessor implements DataProcessor {
process(data: string): ProcessedData throws ValidationError {
if (!data.trim()) {
throw new ValidationError('Data cannot be empty'); // ✅ Valid
}
return { processed: data.trim() };
}
}
function riskyOperation(): string throws Error {
if (Math.random() > 0.5) {
throw new TypeError('Random failure'); // ❌ Error: TypeError not declared in throws clause
}
throw new Error('Expected failure'); // ✅ Valid - Error is declared
}
// Function without throws clause cannot throw
function safeFunction(): string {
throw new Error('Oops'); // ❌ Error: Function does not declare any exceptions in throws clause
}
// TypeScript can infer throws clause from explicit throws in function body
function inferredThrower(value: unknown) /* throws TypeError | RangeError */ {
if (typeof value !== 'number') {
throw new TypeError('Value must be a number'); // Inferred: TypeError
}
if (value < 0) {
throw new RangeError('Value must be non-negative'); // Inferred: RangeError
}
return value.toString();
}
// TypeScript infers: function inferredThrower(value: unknown): string throws TypeError | RangeError
// Mixed explicit and inferred throws
function mixedThrower(data: string): number throws SyntaxError {
if (!data) {
throw new TypeError('Data is required'); // ❌ Error: TypeError not in explicit throws clause
}
if (data === 'invalid') {
throw new SyntaxError('Invalid data format'); // ✅ Valid - SyntaxError is declared
}
return parseInt(data);
}
// Conditional throws inference
function conditionalInference(condition: boolean) {
if (condition) {
throw new Error('Condition failed'); // Inferred: Error
}
// TypeScript infers: throws Error (only when condition is true)
return 'success';
}
#### Arrow Functions with Throws Clauses
```typescript
// Arrow functions support throws clauses too
const asyncParser = async (input: string): Promise<number> throws TypeError => {
if (!input) {
throw new TypeError('Input is required'); // ✅ Valid
}
return parseInt(input);
};
// Generic arrow function with conditional throws
const conditionalThrower = <T>(value: T): string throws T extends Error ? never : TypeError => {
if (value instanceof Error) {
return value.message; // No exception thrown when T extends Error
}
if (typeof value !== 'string') {
throw new TypeError('Value must be string or Error'); // ✅ Valid when T doesn't extend Error
}
return value;
};
Functions must explicitly declare throws clauses to call other functions that throw exceptions:
// ❌ Functions without throws clauses cannot call throwing functions
function caller() {
parseNumber('123'); // Error: Function throws but not declared in throws clause
}
// ✅ Explicit empty throws clause allows any exceptions
function callerWithEmptyThrows() throws {
parseNumber('123'); // Valid - can rethrow any exceptions
}
// ✅ Explicit specific throws clause must be compatible
function callerWithSpecificThrows() throws TypeError, RangeError {
parseNumber('123'); // Valid - throws clause covers TypeError and RangeError
}
Note: Throws inference determines a function's signature, but validation requires explicit throws declarations for calling throwing functions.
This fork is based on Microsoft's TypeScript. For the original project, documentation, and community resources, see below:
TypeScript is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the playground, and stay up to date via our blog and Twitter account.
Find others who are using TypeScript at our community page.
For the latest stable version:
npm install -D typescript
For our nightly builds:
npm install -D typescript@next
There are many ways to contribute to TypeScript.
- Submit bugs and help us verify fixes as they are checked in.
- Review the source code changes.
- Engage with other TypeScript users and developers on StackOverflow.
- Help each other in the TypeScript Community Discord.
- Join the #typescript discussion on Twitter.
- Contribute bug fixes.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
For details on our planned features and future direction, please refer to our roadmap.