Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic "object" syntax for Map initialization and key-value iteration #83

Open
sirisian opened this issue Jan 4, 2023 · 2 comments
Open

Comments

@sirisian
Copy link
Owner

sirisian commented Jan 4, 2023

This is to make sure type proposals using generics works without conflicts with future library features. The big picture of generic objects is to allow very compact Map initialization and key-value iteratation. Record generics would use an identical syntax as below.

Note that sets are already elegant:

const a:Set<uint32> = [0, 1, 2, 3];

Generic object syntax would look like:

{}<K, V>

This allows one to define key and value types for every object. This is mostly useful on maps.

Currently one can do:

const a = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three']
]);
const b = new Map(Object.entries({
  1: 'one',
  2: 'two',
  3: 'three'
}));

Turns into this (if you assume the key was supposed to be an uint32 and not a string) if you use the implicit constructor casting:

const a:Map<uint32, string> = {
  1: 'one',
  2: 'two',
  3: 'three'
}<uint32, string>;

The generic object syntax would be ordered. So objects are inserted into the map in the order they appear.

In the far future this would be changed to:

const a:Map<...> = {
  1: 'one',
  2: 'two',
  3: 'three'
}<uint32, string>;

The syntax supports any key types, so strings aren't a limitation.

class A {}
const a:Map<A, string> = {
  new A(): 'one',
  new A(): 'two',
  new A(): 'three'
}<A, string>;

If the key is a string it does require quotes in this syntax or its is treated as an identifier.

const a:Map<string, string> = {
  '1': 'one',
  '2': 'two',
  '3': 'three'
}<string, string>;

Note that template strings are used for computed strings in this syntax. Consider:

const s = 'a';
const a = {
  [`${s}bc`]: [0]
}<[]<string>, []<uint32>>;

Arrays can be keys. Not sure what that means, but it's allowed in this syntax. I've never needed it.

Iteration looks like:

for (const [k, v] of { 1: 'one', 2: 'two', 3: 'three' }<uint32, string>) {
  // k, v
}
@jaens
Copy link

jaens commented Sep 8, 2024

The generic parameter syntax is not backwards compatible and ambiguous (probably technically requiring unlimited lookahead to parse), since [0] < foo is already a valid (if non-sensical) JavaScript less-than expression.

@sirisian
Copy link
Owner Author

@jaens I've been meaning to change this as it was brought to my attention earlier. I'll be using .< in future updates probably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants