-
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
error in type inference when using keyof #15099
Comments
@dardino does |
No. interface IMsg1 { p1: string; }
interface IMsg2 { pn: number; }
interface IMsg3 { pd: Date; }
interface IMessages { // interface that exposes all available messages
M1: IMsg1;
M2: IMsg2;
M3: IMsg3;
}
// writing this:
function Register<T>(pname: keyof T, c: (m: T[keyof T]) => void): void {
}
// and then calling this:
Register<IMessages>("M1", (msg) => {
// in this closure the var "msg" has three types: IMsg1 | IMsg2 | IMsg3
// but I want only the type corresponding to "M1" that is IMsg1
}); to achieve this goal I need to write this: function Register<T, P extends keyof T>(pname: P, c: (m: T[P]) => void): void {
}
Register<IMessages, "M1">("M1", (msg) => {
// in this closure msg type is correctly IMsg1.
}); |
The error is coming from the generic parameters. If you do: declare function test<T, K extends keyof T>(obj: T, pName: K, callback: (data: T[K]) => void): void;
let obj: TestObj;
test(obj, 'P1', data => {
// 'data' is inferred as 'string' here
}); TypeScript (as of the version in the playground) supports either specifying all generic parameters or none of them. |
In your example you need to give an object as first parameter. // My framework defined method (framework doesn't know the available frames and their commands)
function SendCommandToIFrame<T, P extends keyof T>(key: P, msg: T[P]) {
window.postMessage({
command: key,
body: msg
}, "*");
}
// region User owned file:
type ImportCommand = { Name: string, Type: string };
type ExportCommand = { OriginalName: string, Type: string };
type AvailableIFrames = { Iframe1: ImportCommand, Iframe2: ExportCommand };
SendCommandToIFrame<AvailableIFrames, "Iframe1">("Iframe1", {
Name: "prova.wav",
Type: "audio/wav"
});
SendCommandToIFrame<AvailableIFrames, "Iframe2">("Iframe2", {
OriginalName: "prova.wav",
Type: "audio/wav"
}); |
looks like a duplicate of #10571 |
TypeScript Version: 2.2.1
Code
Expected behavior:
compile with no errors.
Actual behavior:
compile error:
playground
the only way I found is to write P1 "twice":
but in my honest opinion this is not so good.
The text was updated successfully, but these errors were encountered: