Typescript: Add anonymous type declarations

Created on 6 Aug 2017  路  8Comments  路  Source: microsoft/TypeScript

This issue is branching out of discussion in #17636, and largely intended to support that feature.

In the language as it stands today, this would look something like

type A<T> = ( type <U> = {value: U}; )<T>;

This is really not very useful. However, #17636 proposes type declaration overloading, which would allow type switching and filtering within the type system. Anonymous type declarations would allow for inline type switches, reducing the need for global type declarations, and support a further proposal that would alleviate the need for #6606, see #17641.

With type declaration overloads, these anonymous type declarations may look something like

type Foo<T> = {
    value: (
        type <U extends number> = {aNumber: number};
        type <U> = {aDefault: U};
    )<T>
};

For details of how the overloading works, see #17636.

Anonymous type declarations (ATDs?) should probably be allowed in interfaces too, such that Foo<T> above could be an interface.

Duplicate Suggestion

All 8 comments

I'm hugely in favor of this proposal. As noted in #17636, I would only allow overloading as part of this proposal, not on its own, to alleviate concerns with ordering and declaration merging.

More generally, we need support for generic values; i.e. the ability to add arbitrary levels of type abstraction to any type expression. If I have the type Foo<T>, I should be able to declare const x: <A> Foo<A>, just as in other languages you can do forall a. Foo a, or forall a. forall b c. Foo a b c. Currently this is possible in a special cased form for function values, i.e. we can write const x: <T>(t: T) => <U>(u: U) => Foo<T, U>, but not for any other kinds of values. I've tried to lay out a motivating example for this in #17574

@masaeedu

That's a really interesting point, and to be honest I'm not _nearly_ experienced enough with the right languages to be able to process it super easily. Once I've got my head around it I'll have a think about how that could play nicely with the rest of the little network of suggestions that have fallen out of #17636.

Is that suggestion something you can see fitting in nicely alongside these others? Does it clash in any way, or make anything else redundant? Your wording posting here indicates that maybe you think #17574 would cover the requirement for this?

@TheOtherSamP No, the things you are suggesting (as far as I understand at least) seem like they would solve lots of my problems. I'm just going around trying to reference "prior art" concepts that are similar from other languages, so people involved can study those to get a feel for the tradeoffs involved and perhaps pick simpler, more general designs.

To put it another way, if we end up implementing this instead of #17574, I would still be able to encode "polymorphic values" using this feature. The two requests are more or less equivalent in power, just different in syntax.

However it subjectively "feels" more natural to me to simply express this feature as a generalization of generic functions. Just as we say "for all types T, a function that embeds T in an array" is <T> (x: T) => T[], we should be able to say "for all types T, a Fooer of Ts" is <T> Fooer<T>, and "a function that returns, for all types T, a fooer of Ts" is () => <T> Foo<T>. Syntax negotiable.

@masaeedu

That's interesting. As someone who doesn't have a background in type theory or the relatively obscure (well, ish) type-heavy functional languages like Haskell, that's pretty unintuitive for me. It may of course be really simple and easy once you get to play with a working example for two minutes. I suspect that I represent the majority of TypeScript users in that respect though.

Would you be able to provide a couple of little examples of side-by-side comparisons of the two approaches to some simple problems so we can do a more direct comparison?

Turns out internally these already exist, more related snippets in that checker.ts too big for Github search to check.

We now have conditional types, which seem to solve the use cases presented here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RyanCavanaugh picture RyanCavanaugh  路  205Comments

blakeembrey picture blakeembrey  路  171Comments

chanon picture chanon  路  138Comments

OliverJAsh picture OliverJAsh  路  242Comments

sandersn picture sandersn  路  265Comments