Typescript: Proposal: allow type arguments of generic being named

Created on 16 Mar 2018  路  4Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.7.0-dev.201xxxxx


Search Terms: named generic type parameters / arguments

Code

interface UserInfo { }
var usersMap: Map<sessionId: string, info: UserInfo>;

Expected behavior:
No error, Map<sessionId: string, info: UserInfo> should be equivalent to Map<string, UserInfo> .

Actual behavior:
Syntax error: Generic type 'Map' requires 2 type argument(s).

Playground Link:
https://www.typescriptlang.org/play/#src=interface%20UserInfo%20%7B%20%7D%0D%0Avar%20usersMap%3A%20Map%3CsessionId%3A%20string%2C%20info%3A%20UserInfo%3E%3B

Rationale:
Without a name, it is not often immediately clear what a type argument really mean. Take Map<string, UserInfo> as an example, is the first argument a sessionId, a userId or something else? In contrast, Map<sessionId: string, info: UserInfo> or Map<sessionId: string, UserInfo> is very clear.

The name of a type argument doesn't affect the actual type, just like the name of argument of a function type.

Suggestion Too Complex

Most helpful comment

It's the same with normal function calls:

let result = doStuff('foo', true, 3.14, 42); // what do all these mean?

The usual solutions are to either (a) place comments labeling each argument, or (b) pass an options object so callers have to specify key/value pairs, which is both extensible and self-documenting.

You could take both of these approaches with generics too. For example:

// Option A:
interface UserInfo { }
var usersMap: Map</*sessionId:*/ string, /*info:*/ UserInfo>;


// Option B:
interface UserInfo { }
type MyMap<T extends {sessionId: any, info: any}, U = T['sessionId'], V = T['info']> = Map<U, V>;

let usersMap: MyMap<{sessionId: string, info: UserInfo}>;

All 4 comments

When would the name sessionId ever get used by the compiler? It seems to me that this is better left to a comment.

It's the same with normal function calls:

let result = doStuff('foo', true, 3.14, 42); // what do all these mean?

The usual solutions are to either (a) place comments labeling each argument, or (b) pass an options object so callers have to specify key/value pairs, which is both extensible and self-documenting.

You could take both of these approaches with generics too. For example:

// Option A:
interface UserInfo { }
var usersMap: Map</*sessionId:*/ string, /*info:*/ UserInfo>;


// Option B:
interface UserInfo { }
type MyMap<T extends {sessionId: any, info: any}, U = T['sessionId'], V = T['info']> = Map<U, V>;

let usersMap: MyMap<{sessionId: string, info: UserInfo}>;

You can just do

type SessionId = string;

And then use that type.

This seems to introduce much more complexity than it produces in value.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DanielRosenwasser picture DanielRosenwasser  路  3Comments

dlaberge picture dlaberge  路  3Comments

seanzer picture seanzer  路  3Comments

bgrieder picture bgrieder  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments