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

Suggestion: type property names as string literal types #7722

Closed
alitaheri opened this issue Mar 29, 2016 · 2 comments
Closed

Suggestion: type property names as string literal types #7722

alitaheri opened this issue Mar 29, 2016 · 2 comments
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@alitaheri
Copy link

Consider this interface:

interface A {
  foo: string;
  bar: Function;
}

With an operator such as membersof we can have this type:

type MembersofA = membersof A; // equivalent of type MembersofA = 'foo' | 'bar';

Some caveats:

  1. Deceleration merging: I think the compiler is smart enough to resolve all merged properties before building the type for membersof.
  2. Inheritance: If the compiler is smart enough to handle 1, this is a piece of cake 😄
  3. Index signatures: In case we have an interface like this:
interface A {
  foo: string;
  [property: string]: any;
}

The type should turn into: 'foo' | string. Although I'm not so sure about this.
4. new and function signature: I think these can be ignored safely:

interface A {
  new ();
  (bar: number): void;
  foo: string;
}
type MembersofA = membersof A; // 'foo'
  1. Other type constructs:
    • class: public members?
    • enum: members, should be easy. maybe even easy for constant enums
    • namespace: treated like interfaces
    • type alias, union/intersection: doesn't make sense, does it?

There are many use cases. immutable js is the best one:

import {Map} from 'immutable';

interface MapShape {
  foo: number;
  bar: string;
  baz: boolean;
}

const map = new Map<MapShape>();

map.set('blah', 1); // error, unless [other: string]: any; is added to MapShape

Accompanied by #6080 we can have type safety too:

map.set('bar', 1); // error: 1 is not string

Map would look like this:

class Map<T> {
   set(prop: membersof T, value: any): Map<T>;
}

// or with "Value of string literal type as property names" (#6080)

class Map<T> {
   set<U extends membersof T>(prop: U, value: T[U]): Map<T>;
}
// Although this might need to have the output of membersof T to be extensible!

This is easier to implementation than #1295.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jun 7, 2016

Also related is #1579 (comment). Here it's called membersof, there it's called memberof.

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Jun 7, 2016
@DanielRosenwasser DanielRosenwasser changed the title Suggestion: interface members as string literal types Suggestion: type property names as string literal types Jun 7, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Nov 2, 2016

This should be addressed by keyof operator introduced in #11929

@mhegazy mhegazy added Fixed A PR has been merged for this issue and removed Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Nov 2, 2016
@mhegazy mhegazy closed this as completed Nov 2, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants