Typescript type inference from type parameters
I don't understand why Typescript can't properly infer the types in the following case that involves inference from type parameters. (This question is similar to TypeScript type inference issue but is a somewhat different case. The answer may be the same, though, that I'm just out of luck!)
// A base class for a dialog taking parameter of type P
// and returning result of type R.
class BaseDialog<P, R> { p: P; r: R; }
class ValueDialog extends BaseDialog<string, number> {}
// A function that shows the dialog
show<T extends BaseDialog<P, R>, P, R>(dlg: Type<T>, param: P): Promise<R> {}
Note: To simplify the method signature, I'm using Angular's Type:
export interface Type<T> extends Function {
new (...args: any): T;
}
Now, when I call the method show, as follows, the R type is not correctly inferred:
show(ValueDialog, "name").then(r => console.log(r));
The compiler infers:
T = ValueDialog
P = string
R = {}
Since T is correctly inferred, you'd think the compiler could infer P and R from ValueDialog's definition, but it doesn't.
I can fix this, of course, by manually specifying the types, but that's pretty ugly. I can also fix it by making P and R the same, but that isn't the functionality I want.
How can I define show() so that it correctly infers R?
typescript type-inference
add a comment |
I don't understand why Typescript can't properly infer the types in the following case that involves inference from type parameters. (This question is similar to TypeScript type inference issue but is a somewhat different case. The answer may be the same, though, that I'm just out of luck!)
// A base class for a dialog taking parameter of type P
// and returning result of type R.
class BaseDialog<P, R> { p: P; r: R; }
class ValueDialog extends BaseDialog<string, number> {}
// A function that shows the dialog
show<T extends BaseDialog<P, R>, P, R>(dlg: Type<T>, param: P): Promise<R> {}
Note: To simplify the method signature, I'm using Angular's Type:
export interface Type<T> extends Function {
new (...args: any): T;
}
Now, when I call the method show, as follows, the R type is not correctly inferred:
show(ValueDialog, "name").then(r => console.log(r));
The compiler infers:
T = ValueDialog
P = string
R = {}
Since T is correctly inferred, you'd think the compiler could infer P and R from ValueDialog's definition, but it doesn't.
I can fix this, of course, by manually specifying the types, but that's pretty ugly. I can also fix it by making P and R the same, but that isn't the functionality I want.
How can I define show() so that it correctly infers R?
typescript type-inference
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07
add a comment |
I don't understand why Typescript can't properly infer the types in the following case that involves inference from type parameters. (This question is similar to TypeScript type inference issue but is a somewhat different case. The answer may be the same, though, that I'm just out of luck!)
// A base class for a dialog taking parameter of type P
// and returning result of type R.
class BaseDialog<P, R> { p: P; r: R; }
class ValueDialog extends BaseDialog<string, number> {}
// A function that shows the dialog
show<T extends BaseDialog<P, R>, P, R>(dlg: Type<T>, param: P): Promise<R> {}
Note: To simplify the method signature, I'm using Angular's Type:
export interface Type<T> extends Function {
new (...args: any): T;
}
Now, when I call the method show, as follows, the R type is not correctly inferred:
show(ValueDialog, "name").then(r => console.log(r));
The compiler infers:
T = ValueDialog
P = string
R = {}
Since T is correctly inferred, you'd think the compiler could infer P and R from ValueDialog's definition, but it doesn't.
I can fix this, of course, by manually specifying the types, but that's pretty ugly. I can also fix it by making P and R the same, but that isn't the functionality I want.
How can I define show() so that it correctly infers R?
typescript type-inference
I don't understand why Typescript can't properly infer the types in the following case that involves inference from type parameters. (This question is similar to TypeScript type inference issue but is a somewhat different case. The answer may be the same, though, that I'm just out of luck!)
// A base class for a dialog taking parameter of type P
// and returning result of type R.
class BaseDialog<P, R> { p: P; r: R; }
class ValueDialog extends BaseDialog<string, number> {}
// A function that shows the dialog
show<T extends BaseDialog<P, R>, P, R>(dlg: Type<T>, param: P): Promise<R> {}
Note: To simplify the method signature, I'm using Angular's Type:
export interface Type<T> extends Function {
new (...args: any): T;
}
Now, when I call the method show, as follows, the R type is not correctly inferred:
show(ValueDialog, "name").then(r => console.log(r));
The compiler infers:
T = ValueDialog
P = string
R = {}
Since T is correctly inferred, you'd think the compiler could infer P and R from ValueDialog's definition, but it doesn't.
I can fix this, of course, by manually specifying the types, but that's pretty ugly. I can also fix it by making P and R the same, but that isn't the functionality I want.
How can I define show() so that it correctly infers R?
typescript type-inference
typescript type-inference
edited Nov 23 '18 at 15:35
RDG
asked Nov 23 '18 at 15:06
RDGRDG
386
386
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07
add a comment |
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07
add a comment |
1 Answer
1
active
oldest
votes
You ca use a conditional type to extract type R parameter from the base type. You will need to use the R type in some way for this to work :
export interface Type<T> extends Function {
new (...args: any): T;
}
class BaseDialog<P, R> {
value: R //we need to use R in some way for the parameter to make a difference
}
class ValueDialog extends BaseDialog<string, number> {}
type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never;
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;
show(ValueDialog, "name").then(r => console.log(r)); // r is now string
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449020%2ftypescript-type-inference-from-type-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You ca use a conditional type to extract type R parameter from the base type. You will need to use the R type in some way for this to work :
export interface Type<T> extends Function {
new (...args: any): T;
}
class BaseDialog<P, R> {
value: R //we need to use R in some way for the parameter to make a difference
}
class ValueDialog extends BaseDialog<string, number> {}
type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never;
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;
show(ValueDialog, "name").then(r => console.log(r)); // r is now string
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
add a comment |
You ca use a conditional type to extract type R parameter from the base type. You will need to use the R type in some way for this to work :
export interface Type<T> extends Function {
new (...args: any): T;
}
class BaseDialog<P, R> {
value: R //we need to use R in some way for the parameter to make a difference
}
class ValueDialog extends BaseDialog<string, number> {}
type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never;
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;
show(ValueDialog, "name").then(r => console.log(r)); // r is now string
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
add a comment |
You ca use a conditional type to extract type R parameter from the base type. You will need to use the R type in some way for this to work :
export interface Type<T> extends Function {
new (...args: any): T;
}
class BaseDialog<P, R> {
value: R //we need to use R in some way for the parameter to make a difference
}
class ValueDialog extends BaseDialog<string, number> {}
type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never;
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;
show(ValueDialog, "name").then(r => console.log(r)); // r is now string
You ca use a conditional type to extract type R parameter from the base type. You will need to use the R type in some way for this to work :
export interface Type<T> extends Function {
new (...args: any): T;
}
class BaseDialog<P, R> {
value: R //we need to use R in some way for the parameter to make a difference
}
class ValueDialog extends BaseDialog<string, number> {}
type ExtractResult<T extends BaseDialog<any, any>> = T extends BaseDialog<any, infer R> ? R : never;
// A function that shows the dialog
declare function show<T extends BaseDialog<P, any>, P>(dlg: Type<T>, param: P): Promise<ExtractResult<T>>;
show(ValueDialog, "name").then(r => console.log(r)); // r is now string
answered Nov 23 '18 at 15:12
Titian Cernicova-DragomirTitian Cernicova-Dragomir
65.6k34361
65.6k34361
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
add a comment |
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
1
1
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
This works! I can (mostly) follow the ExtractResult type, but I could never have come up with this on my own! I'm from the other link that this is the only way to infer types from a type parameter. Thank you for the help!
– RDG
Nov 24 '18 at 19:54
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449020%2ftypescript-type-inference-from-type-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This might help: stackoverflow.com/questions/53448100/…
– Titian Cernicova-Dragomir
Nov 23 '18 at 15:07