- Notifications
You must be signed in to change notification settings - Fork 13.2k
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Description
keyof T and T[K]
Note about terminology
keyofis a type operator. Note, name change from Keysof type operator #10425 tokeyof; since the type name represents one value and not the whole value domain. this is inline with the other names of types e.g. we callnumberand notnumbers,- Henceforth, formal names of these type operators:
keyof T=> Index Type QueryT[K]=> Indexed Access Type
Details
keyof T
known properties and index signatures (
number | stringfor string indexers andnumberfor numeric indexers)Examples:
keyof{a: number, b:string}=>"a" | "b"keyof{[x: string] : number }=>string | numberkeyof{[x: number] : number }=>numberkeyof{}[]=>"toString" | "pop" |...| numberkeyof{a: number, b:string } |{a: number, c:string}=>"a"keyof{a: number, b:string } &{a: number, c:string}=>"a" | "b" | "c"
What about symbols?
- symbols not supported yet. we need to make symbols literal types first.
privateandprotected
A piece of trivia, accessing private and protected properties are allowed for index access todayclassC{privatex;}letc: C;c.x;// not allowedc["x"];// is allowed today
- should this apply to the new type operator:
ts type T = C["x"]; // OK or not? - for
nameofin C# does not do this either- it exists at run time
- against
- we should not carry past misdeeds in new features
- it exposes implementation details
- not valid for declaration emit, since we strip out the type
- Decision
keyof Tis public-only known properties, private and protected properties are not included
- should this apply to the new type operator:
T[K]
- only index with a type
Kparameter iff it is constraint to thekeyof T - this grantees that the output is type of a property
- can be used with literal types
classThing{name: string;width: number;}typeq1=Thing["name"];// stringtypeq2=Thing["name"|"width"];//string | numbertypeq3=Thing["name"|"foo"];// Error "foo" is not a property on ThingPutting them together
functiongetProperty<T,KextendskeyofT>(obj: T,key:K){returnobj[key];// T[K]}functionsetProperty<T,KextendskeyofT>(obj: T,key:K,value: T[K]){obj[K]=value;}varthing: Thing;varthingList: Thing[];getPropeprty(thing,"foo")// ErrorgetPropeprty(thing,"name")// stringgetPropeprty(thingList,1)// ThinggetPropeprty(thingList,1+2)// ThingsetPropoerty(thing,"name","my name");// OKsetPropoerty(thing,"name",3);// ErrorIndex access unification
- The way we do
T[K]for a type should be the same as that for an expressiont[k]. - so
thing[condition ? "name" : "width"];// should be string | numberIssues
Variance
Consider this:
setPropoerty(thing,condition? "name" : "width","string");- this is allowed today, but it is unsafe...
Keyof Tshould be a union for types of all properties for read, but an intersection for write. - This is the same behavior we have today for indexers anyways:
interfaceI{a: number;b: string;[x: string] : number|string;}constk=condition? "a" : "b";x[k]// number | string;x[k]="bar";// allowed but not safe- We are getting close to the "safe variance" glass ceiling
- solving these all would need to add variance in the type system
- a readonly, writeonly, and readwrite types
- this applies to class properties, parameters, everything
- this would be a large braking change, and have to be done holistically
- the safer it would be the tighter it would be for users to use
Where we can land:
- For expressions, it would be an error i.e.
thing[condition ? "name" : "width"]="bar";/// Error, we know unsafe - but not for generic type argument
setProperty(thing,condition ? "name" : "width","bar");// OK Note about readonly:
- you can write a readonly propoerty using
setPropoerty. - there is not much we can do here. the time where this would be observed is at instantiation time, which is too late at that point to report errors.
- and again it goes back to variance, you need
readonly keyof Tandreadwrite keyof T.
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings