Suggestion: shorthand for templated type to extend and default to the same type
Search Terms
default extends equals generics = template types is
Suggestion
Can we have a way to declare that a templated (generic) type both extends and is = a type value without repeating the type value?
declare function example<T extends Base = Base>(value: T): T;
A clean way to do this would be to allow the is keyword following a generic type:
declare function example<T is Base>(value: T): T;
Failing that, how about omitting the first type value?
declare function example<T extends = Base>(value: T): T;
Use Cases
Generic parameters with extended and default values set to the same are a reasonable pattern:
declare function querySelector<E extends Element = Element>(selectors: string): E | null;
In larger type definitions with many generics, these extends+= definitions can get a little cumbersome:
type BitAddThree<
A extends Bit = Bit,
B extends Bit = Bit,
C extends Bit = Bit
> =
[A, B, C] extends [0, 0, 0] ? [0, 0] :
// etc. etc.
[Bit, Bit, Bit];
Examples
declare function querySelector<E is Element>(selectors: string): E | null;
declare function querySelector<E extends = Element>(selectors: string): E | null;
type BitAddThree<A is Bit, B is Bit, C is Bit> = // ...
type BitAddThree<A extends = Bit, B extends = Bit, C extends = Bit> = // ...
Checklist
My suggestion meets these guidelines:
- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- [x] This feature would agree with the rest of TypeScript's Design Goals.
Personally I prefer the extends = form, as is creates a whole new operator (which means something new and not intuitive we have to learn as well as one less word we can use for other things). It's a little bit longer but still saves a lot of space, especially when you start coming up with very specific type names:
type Something<T, K extends ComplexPropertyNames<T> = ComplexPropertyNames<T>> = ...
vs
type Something<T, K extends = ComplexPropertyNames<T>> = ...
Any news on this? This would save me soooo much space. Many times I have ternary expressions on top of this and I end up formatting them like this to try to make it clear the default is the same (and so I don't accidentally make them different) and it takes up quite a bit of space, especially in classes that require 3-4 type parameters.
someMethod<
T extends
string | number =
string | number
TOther extends
T extends string ? TForString : TForNumber = // sometimes i even have to split these into their own lines
T extends string ? TForString : TForNumber,
> (t:T, other: TOther) {}
And if TFor... is a complex type with a few type parameters, 😱.
Being able to do extends = or something like that would be amazing. It would save me 2 lines or more per type parameter!
someMethod<
T extends = string | number
TOther extends = T extends string ? TForString : TForNumber
> (t:T, other: TOther) {}
I've come across this situation in my journey into TS, especially investigating patterns around typed plugin systems for libraries. Here is a small tweet describing my sentiment: https://twitter.com/tannerlinsley/status/1365832565278400515
I would really love to see this type of syntax improvement land. I would also be willing to help implement it with enough guidance.
I’d love this, please also consider this possible syntax: https://github.com/microsoft/TypeScript/issues/55826
I was looking for this issue & would love this. This isn't even complicated to implement or anything as it's not a new concept or anything, simple a human shortcut syntax. Weird even after 6 years, no answer from anyone
There are nearly 3,000 open suggestions, you can't really expect all of them to be in the language. The documentation would be the size of an encyclopedia.
@RyanCavanaugh There are nearly 3,000 open suggestions, you can't really expect all of them to be in the language. The documentation would be the size of an encyclopedia.
Such a dismissive and effortless answer... I never went close to implying that all 3000 open suggestions should be merged... It's unfortunate you see it this way.
Typescript already has a lot of shortcuts impleted in the exact same philosophy like optional properties ({ id?: string } instead of { id: string | undefined }) and utility types (Readonly<>, Partial/Required<>).
This isn't asking for a functionality/concept/type addition/removal/change or anything remotely non-trivial, just to continue this philosophy direction in one of the most dumb and simple way ever, providing long-term readability to everyone.
And obviously, this will not change a single thing in any typescript codebase ever made since the pattern, while intuitive (another plus), isn't used anywhere.
But no since we went past 5k pull requests we can just throw the "You never implied/said this but you really expect all of the typescript issues to be implemented?" joker card i guess.
I don't really know you were going for with "Weird even after 6 years, no answer from anyone". What answer was expected, if not to add the feature?
I don't really know you were going for with "Weird even after 6 years, no answer from anyone". What answer was expected, if not to add the feature?
"No answer from anyone in 6 years" implied that there aren't as many comments on this issue than I expected (regarding how the post has the tag "Awaiting More Feedback"). I don't think it's a very niche issue so that was surprising, but then again I only found out about the issue after asking claude to look up any blog/website related to my issue (couldn't find this issue by myself) so maybe it's because the title has complicated vocabulary for the simplicity of the content?