-
Notifications
You must be signed in to change notification settings - Fork 226
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
EventEmitter types still broken on Typescript 3.9 RC #225
Comments
Thanks, @sandersn. I will have a look, but doesn't this point to a regression in TS 3.9, given that it seems to work in TS 3.8 (and below)? |
@sandersn I just tried this with |
@gfmio I can repro this by running $ tsc index.d.ts From the root of the eventemitter3 repo. Can you double-check that your globally installed version of typescript is 3.9 RC or higher? (I haven't tried with 3.9.0-beta, just 3.9.1-rc and 4.0.0-dev) |
I'll take another look at the types and see why they broke in 3.9. |
@sandersn I think that this is due the conditional type I'm using in ValidEventTypes: export type ValidEventTypes<T = any> = string | symbol | T extends {
[K in keyof T]: any[] | ((...args: any[]) => void);
}
? T
: never;
export type ArgumentMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => void
? Parameters<T[K]>
: T[K] extends any[]
? T[K]
: any[];
};
export type EventListener<
T extends ValidEventTypes,
K extends EventNames<T>
> = T extends string | symbol
? (...args: any[]) => void
: (...args: ArgumentMap<T>[K]) => void; As I'm removing This conditional type represents an object with arbitrary keys whose keys are all |
The lack of errors in 3.8 is due the behaviour of In this case I'm trying to figure out a way to get rid of the error, but in the meantime, this is closer to your prose description of export type ValidEventTypes = string | symbol | { [s: string]: any[] | ((...args: any[]) => void) }; |
@sandersn Thanks for the heads up. I've thought about it and can't we just do the following? export type ValidEventTypes = string | symbol | Record<any, any[] | ((...args: any[]) => void)>; |
Yes, that seems to work, although I'm suspicious, because it should be equivalent to my attempt, which still has the 3.9 error. I'm not sure why that is. @weswigham do you have any ideas? |
The |
So, the valid key types that the Record should really accept are |
I think I've found a solution by using export type ValidEventTypes =
| string
| symbol
| { [K in string | symbol]: any[] | ((...args: any[]) => void) };
export type EventNames<T extends ValidEventTypes> = T extends string | symbol
? T
: keyof T;
export type ArgumentMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => void
? Parameters<T[K]>
: T[K] extends any[]
? T[K]
: any[];
};
export type EventListener<
T extends ValidEventTypes,
K extends EventNames<T>
> = T extends string | symbol
? (...args: any[]) => void
: (...args: ArgumentMap<Exclude<T, string | symbol>>[K]) => void; Can you verify that this works for you as well and that this won't cause any unintended side effects? |
That works for me, and is basically the workaround discussed in the PR that introduced the breaking change, which means that it should be a pretty safe change. |
Typescript 3.9, which should be out some time this week, still has an error when compiling
Here's my tsconfig:
And my index.ts:
The error is here:
"Type 'K' cannot be used to index type 'ArgumentMap'."
I can't tell what's going wrong from a quick glance at the types; there are too many layers of indirection here. My guess is that the compiler just can't find a declaration that says
K
is a legal key ofArgumentMap<T>
— but I couldn't figure out what declaration would work.Discovered in the Typescript nightly tests, where we compile our nightly against the latest shipped types of widely used packages: microsoft/TypeScript#38405
The text was updated successfully, but these errors were encountered: