Typescript type inference from type parameters












2















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?










share|improve this question

























  • This might help: stackoverflow.com/questions/53448100/…

    – Titian Cernicova-Dragomir
    Nov 23 '18 at 15:07
















2















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?










share|improve this question

























  • This might help: stackoverflow.com/questions/53448100/…

    – Titian Cernicova-Dragomir
    Nov 23 '18 at 15:07














2












2








2








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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



















  • 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












1 Answer
1






active

oldest

votes


















0














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





share|improve this answer



















  • 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













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
});


}
});














draft saved

draft discarded


















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









0














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





share|improve this answer



















  • 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


















0














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





share|improve this answer



















  • 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
















0












0








0







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





share|improve this answer













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






share|improve this answer












share|improve this answer



share|improve this answer










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
















  • 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






















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Tonle Sap (See)

I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

Guatemaltekische Davis-Cup-Mannschaft