-
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
keyof R
is not assignable to extends keyof R
#21884
Comments
Looks like things are working as intended here. The type-safe way to get this done would probably require existential types (#14466) which TypeScript doesn't have built-in support for. For fun, here's how you'd need to do it today: type Event<R, K extends keyof R> = { type: K, data: R[K] };
type SomeEvent<R> = <O>(f: <K extends keyof R>(e: Event<R, K>) => O) => O
type SomeParticularEvent<R, K extends keyof R> = <O>(f: (e: Event<R, K>) => O) => O
const narrowSomeEvent = <R, K extends keyof R>(k: K) =>
(someEvent: SomeEvent<R>): someEvent is SomeParticularEvent<R, K> =>
someEvent(e => e.type === k as string);
class Store<R> {
protected events: SomeEvent<R>[] = [];
public on<A extends keyof R>(type: A): R[A] | undefined {
const theEvent = this.events.find(narrowSomeEvent(type))
return theEvent ? theEvent(e => e.data) : undefined;
}
} Might not be worth it to you. Anyway, this doesn't look like a bug to me and perhaps this kind of question belongs on StackOverflow instead. |
The title has it backwards - it's that |
extends keyof R
is not assignable to keyof R
keyof R
is not assignable to extends keyof R
You could also use a type predicate function to convey the narrowing to class Store<R> {
protected events: { type: keyof R, data: R[keyof R] }[] = [];
public on<A extends keyof R>(type: A): R[A] {
return this.events
.find((event): event is { type: A, data: R[A] } => event.type === type)!
.data;
}
}
interface IEvents {
smth: string;
smth2: number;
smth3: boolean;
}
const store = new Store<IEvents>();
const smthEvent = store.on('smth'); |
thx for solutions
|
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
TypeScript Version: 2.7.1
Code
Expected behavior:
No error,
smthEvent
has properstring
typeActual behavior:
or with
smthEvent
hasparameter) data: string | number | boolean
type instead ifstring
No error with TS 2.6.2
Playground Link:
https://www.typescriptlang.org/play/#src=class%20Store%3CR%3E%20%7B%0D%0A%20%20protected%20events%3A%20%7B%20type%3A%20keyof%20R%2C%20data%3A%20R%5Bkeyof%20R%5D%20%7D%5B%5D%20%3D%20%5B%5D%3B%0D%0A%0D%0A%20%20public%20on%3CA%20extends%20keyof%20R%3E(type%3A%20A)%3A%20R%5BA%5D%20%7B%0D%0A%20%20%20%20return%20this.events%0D%0A%20%20%20%20%20%20.find(event%20%3D%3E%20event.type%20%3D%3D%3D%20type)%0D%0A%20%20%20%20%20%20.data%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Ainterface%20IEvents%20%7B%0D%0A%20%20smth%3A%20string%3B%0D%0A%20%20smth2%3A%20number%3B%0D%0A%20%20smth3%3A%20boolean%3B%0D%0A%7D%0D%0A%0D%0Aconst%20store%20%3D%20new%20Store%3CIEvents%3E()%3B%0D%0A%0D%0Aconst%20smthEvent%20%3D%20store.on('smth')%3B
The text was updated successfully, but these errors were encountered: