-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
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
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 data
interface EventType<TName extends string, TData extends any> {
name: TName;
data: TData;
}
class EventEmitter<TEventType extends EventType<string, any>> {
on<TType extends TEventType>(name: TType["name"], listener:(event: TType["data"]) => void):this;
/*...*/
} Usage: type EventTypeA = EventType<'a', { foo: string; }>;
type EventTypeB = EventType<'b', { bar: string; }>;
const emitter = new EventEmitter<EventTypeA | EventTypeB>();
// emitter.on requires that the event name and data match the provided EventType
emitter.on<EventTypeA>('a', (evt) => {
evt.foo;
});
emitter.on(EventTypeB>('b', (evt) => {
evt.bar;
}); |
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: type DispatcherSchema = { [name: string]: { argTypes: any[]; returnType: any } };
class Dispatcher<S extends DispatcherSchema> {
dispatch<K extends keyof S>(name: K, args: S[K]['argTypes']): S[K]['returnType'] {
// ...
}
}
type MySchema = {
"read": { argTypes: [string, number]; returnType: string[]; };
"write": { argTypes: [string, string[], boolean]; returnType: number; };
}
const dispatcher = new Dispatcher<MySchema>();
var result = dispatcher.dispatch("read", ["myfile.txt", 35]); // ok
var result = dispatcher.dispatch("read", "myfile.txt"); // already errors
var result = dispatcher.dispatch("reed", ["myfile.txt", 35]); // already errors
var result = 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...) |
Just downloaded |
Any chance this can make it into 2.1.5? |
With this PR we defer resolution of indexed access types
T[K]
whereT
is generic andK
is non-generic.In the example above, the indexed access type
T['value']
is permitted becauseT
is constrained to a type that has a property namedvalue
. The typeT['value']
behaves like a subtype ofstring | number
because that is the type ofvalue
in the constraint type, and when instantiation substitutes an actual type forT
, the type of thevalue
property in that actual type is substituted forT['value']
.Note that for backwards compatibility reasons, the expression
obj.value
is 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
obj
above is changed toT2<'y'>
the circularity error goes away.Fixes #12651.
Fixes #12723.
Fixes #12744.