Description
Search Terms
generics, type parameters, named parameter, named type parameter, type argument, named type argument
Suggestion
It should be possible to pass type arguments to a generic by name rather than positionally, eg.
interface Foo<T = SomeDefaultType, U> { ... }
// Current syntax
const foo: Foo<SomeDefaultType, string> ...
// Proposed syntax
const foo: Foo<U = string> ...
// yields foo: Foo<SomeDefaultValue, string>
This is loosely inspired on python's named arguments:
def foo(bar = "I'm bar", baz):
...
foo(baz="I'm baz")
Use Cases
Generics only accept positional type arguments. If you have a generic accepting many type arguments, most or all of which having default values such as:
interface Handler<Type = string, TPayload = object, TOutput = void> {
type: Type
handle(payload: TPayload): TOutput
}
Let's say we have a class which implements the Handler interface but the defaults for Type
and TPayload
are fine for us and we only want to specify a type for TOuput
, currently it is mandatory that we pass type arguments for Type
and TPayload
:
class Foo implements Handler<string, object, Promise<number>>
If it was possible to pass type arguments by name we could use the considerably terser form:
class Foo implements Handler<TOutput=Promise<number>>
Examples
Fastify exposes types generic over many parameters with default values, such as
interface FastifyRequest<
HttpRequest = http.IncomingMessage,
Query = DefaultQuery,
Params = DefaultParams,
Headers = DefaultHeaders,
Body = DefaultBody
> { ...
With the proposed syntax we could create specialized interfaces with much less overhead such as
import * as fastify from 'fastify';
const app = fastify();
app.get('/users/:id', async (req: FastifyRequest<Params = {id: string }>, res: FastifyReply) => {
// req.params is strongly typed now
})
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.