GitHub - joshcaughtfire/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
๐ฅ TypeScript with Throws Clause Support
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
โจ Features
- 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
๐ Syntax Examples
Basic Exception Declaration
// 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 (Function Can Rethrow)
// 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 } }
Union Types in Throws Clauses
// 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); }
Generic Throws Clauses with Conditional Types
// 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 Method Signatures
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() }; } }
Type Inference and Validation
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 }
Throws Clause Inference from Function Body
// 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; };
๐จ Important: Explicit Throws Declaration Required
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.
๐ Original TypeScript
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.
Installing
For the latest stable version:
npm install -D typescript
For our nightly builds:
npm install -D typescript@next
Contribute
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.
Documentation
Roadmap
For details on our planned features and future direction, please refer to our roadmap.