Uh oh!
There was an error while loading. Please reload this page.
Defer indexed access T[K] with non-generic K - #12770
Conversation
# Conflicts: # src/compiler/checker.ts # tests/baselines/reference/keyofAndIndexedAccess.js # tests/baselines/reference/keyofAndIndexedAccess.symbols # tests/baselines/reference/keyofAndIndexedAccess.types # tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts
Edan Schwartz (eschwartz)
commented
Dec 8, 2016
I just want to point out that once this is fixed, we should be able to implement a better For example // Encapulate an event's name and datainterfaceEventType<TNameextendsstring,TDataextendsany>{name: TName;data: TData;}classEventEmitter<TEventTypeextendsEventType<string,any>>{on<TTypeextendsTEventType>(name: TType["name"],listener:(event: TType["data"])=>void):this;/*...*/}Usage: typeEventTypeA=EventType<'a',{foo: string;}>;typeEventTypeB=EventType<'b',{bar: string;}>;constemitter=newEventEmitter<EventTypeA|EventTypeB>();// emitter.on requires that the event name and data match the provided EventTypeemitter.on<EventTypeA>('a',(evt)=>{evt.foo;});emitter.on(EventTypeB>('b',(evt)=>{evt.bar;}); |
Edan Schwartz (eschwartz)
commented
Dec 9, 2016
Any idea when this might be released? Should we be expecting a (also, thanks for all the work on this. This is really cool stuff, and I'm having a ton of fun using it) |
I believe I've found an alternative, though less elegant, approach to my dispatcher example that doesn't rely on discriminated unions and might work with the new inference capability described here without any need for additional syntax: typeDispatcherSchema={[name: string]: {argTypes: any[];returnType: any}};classDispatcher<SextendsDispatcherSchema>{dispatch<KextendskeyofS>(name: K,args: S[K]['argTypes']): S[K]['returnType']{// ...}}typeMySchema={"read": {argTypes: [string,number];returnType: string[];};"write": {argTypes: [string,string[],boolean];returnType: number;};}constdispatcher=newDispatcher<MySchema>();varresult=dispatcher.dispatch("read",["myfile.txt",35]);// okvarresult=dispatcher.dispatch("read","myfile.txt");// already errorsvarresult=dispatcher.dispatch("reed",["myfile.txt",35]);// already errorsvarresult=dispatcher.dispatch("write",["myfile.txt","oops",true]);// might error with this PR?It seems promising but I have not tested this yet though (I'm waiting for the pull request to be merged and arrive to the nightly builds). (If this does prove to work I'll probably start applying this pattern literally immediately in my code...) |
Edan Schwartz (eschwartz)
commented
Dec 12, 2016
Just downloaded |
Edan Schwartz (eschwartz)
commented
Jan 3, 2017
Any chance this can make it into 2.1.5? |
With this PR we defer resolution of indexed access types
T[K]whereTis generic andKis non-generic.In the example above, the indexed access type
T['value']is permitted becauseTis constrained to a type that has a property namedvalue. The typeT['value']behaves like a subtype ofstring | numberbecause that is the type ofvaluein the constraint type, and when instantiation substitutes an actual type forT, the type of thevalueproperty in that actual type is substituted forT['value'].Note that for backwards compatibility reasons, the expression
obj.valueis still eagerly resolved to typestring | number. The expression must be explicitly coerced toT['value']using a type annotation or a type assertion in order to get the deferred behavior.This PR also implements better circularity detection and reporting for indexed access types. For example:
Note that circularities may sometimes result only for certain arguments to type parameters.
If the type of
objabove is changed toT2<'y'>the circularity error goes away.Fixes#12651.
Fixes#12723.
Fixes#12744.