Typescript generic interface parameter assignment











up vote
2
down vote

favorite
1












I’m struggling to understand why this example isn’t considered valid by the typescript compiler:



interface IExample<T> {
param: T
}

function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam };
}


The error produced is:



Type 'U' is not assignable to type 'I["param"]'.


My (assumedly incorrect) reading of this snippet is:





  • IExample<T> expects param to have type T.


  • I is a subtype of IExample<U>, meaning param has type U.


  • myParam has type U from the parameter annotation.

  • Therefore myParam should be a valid value for param of I.


Prefixing the return value with <I> clears the error, so why does the error appear in the first place?










share|improve this question


















  • 1




    I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
    – JB Nizet
    Nov 12 at 17:38












  • Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
    – MTCoster
    Nov 12 at 17:54















up vote
2
down vote

favorite
1












I’m struggling to understand why this example isn’t considered valid by the typescript compiler:



interface IExample<T> {
param: T
}

function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam };
}


The error produced is:



Type 'U' is not assignable to type 'I["param"]'.


My (assumedly incorrect) reading of this snippet is:





  • IExample<T> expects param to have type T.


  • I is a subtype of IExample<U>, meaning param has type U.


  • myParam has type U from the parameter annotation.

  • Therefore myParam should be a valid value for param of I.


Prefixing the return value with <I> clears the error, so why does the error appear in the first place?










share|improve this question


















  • 1




    I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
    – JB Nizet
    Nov 12 at 17:38












  • Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
    – MTCoster
    Nov 12 at 17:54













up vote
2
down vote

favorite
1









up vote
2
down vote

favorite
1






1





I’m struggling to understand why this example isn’t considered valid by the typescript compiler:



interface IExample<T> {
param: T
}

function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam };
}


The error produced is:



Type 'U' is not assignable to type 'I["param"]'.


My (assumedly incorrect) reading of this snippet is:





  • IExample<T> expects param to have type T.


  • I is a subtype of IExample<U>, meaning param has type U.


  • myParam has type U from the parameter annotation.

  • Therefore myParam should be a valid value for param of I.


Prefixing the return value with <I> clears the error, so why does the error appear in the first place?










share|improve this question













I’m struggling to understand why this example isn’t considered valid by the typescript compiler:



interface IExample<T> {
param: T
}

function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam };
}


The error produced is:



Type 'U' is not assignable to type 'I["param"]'.


My (assumedly incorrect) reading of this snippet is:





  • IExample<T> expects param to have type T.


  • I is a subtype of IExample<U>, meaning param has type U.


  • myParam has type U from the parameter annotation.

  • Therefore myParam should be a valid value for param of I.


Prefixing the return value with <I> clears the error, so why does the error appear in the first place?







typescript generics






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 at 17:31









MTCoster

2,07421736




2,07421736








  • 1




    I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
    – JB Nizet
    Nov 12 at 17:38












  • Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
    – MTCoster
    Nov 12 at 17:54














  • 1




    I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
    – JB Nizet
    Nov 12 at 17:38












  • Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
    – MTCoster
    Nov 12 at 17:54








1




1




I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
– JB Nizet
Nov 12 at 17:38






I would have expected a different error message: something like { param: U } isn't assignable to generic type I: I is an unknown type, which could have many more attributes and methods than just param. So { param: myParam } is almost guaranteed to not be of type I.
– JB Nizet
Nov 12 at 17:38














Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
– MTCoster
Nov 12 at 17:54




Found a duplicate which I missed before posting: stackoverflow.com/q/40690797/1813169
– MTCoster
Nov 12 at 17:54












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










The problem is that I might have other required properties in addition to param. Typescript will force your generic function implementation to return a valid value for any I that satisfies the constraint of extending IExample<U>, and it does not.



For example:



interface DerivedIExample extends IExample<number> {
other : string
}
let o = testFunc<number, DerivedIExample>(0)
o.other // required by the DerivedIExample but not assigned


In your simple example, it would be best to do away with I completely:



function testFunc<U>(myParam: U): IExample<U> {
return { param: myParam };
}


You can force the compiler to accept your code using a type assertion but as outlined above that is not type-safe:



function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam } as I; // NOT TYPE SAFE! USE WITH CARE !
}





share|improve this answer





















  • I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
    – MTCoster
    Nov 12 at 17:52










  • @MTCoster your call, you could ... the message is misleading ...
    – Titian Cernicova-Dragomir
    Nov 12 at 17:54






  • 2




    It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
    – MTCoster
    Nov 12 at 18:08











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',
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%2f53267269%2ftypescript-generic-interface-parameter-assignment%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








up vote
1
down vote



accepted










The problem is that I might have other required properties in addition to param. Typescript will force your generic function implementation to return a valid value for any I that satisfies the constraint of extending IExample<U>, and it does not.



For example:



interface DerivedIExample extends IExample<number> {
other : string
}
let o = testFunc<number, DerivedIExample>(0)
o.other // required by the DerivedIExample but not assigned


In your simple example, it would be best to do away with I completely:



function testFunc<U>(myParam: U): IExample<U> {
return { param: myParam };
}


You can force the compiler to accept your code using a type assertion but as outlined above that is not type-safe:



function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam } as I; // NOT TYPE SAFE! USE WITH CARE !
}





share|improve this answer





















  • I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
    – MTCoster
    Nov 12 at 17:52










  • @MTCoster your call, you could ... the message is misleading ...
    – Titian Cernicova-Dragomir
    Nov 12 at 17:54






  • 2




    It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
    – MTCoster
    Nov 12 at 18:08















up vote
1
down vote



accepted










The problem is that I might have other required properties in addition to param. Typescript will force your generic function implementation to return a valid value for any I that satisfies the constraint of extending IExample<U>, and it does not.



For example:



interface DerivedIExample extends IExample<number> {
other : string
}
let o = testFunc<number, DerivedIExample>(0)
o.other // required by the DerivedIExample but not assigned


In your simple example, it would be best to do away with I completely:



function testFunc<U>(myParam: U): IExample<U> {
return { param: myParam };
}


You can force the compiler to accept your code using a type assertion but as outlined above that is not type-safe:



function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam } as I; // NOT TYPE SAFE! USE WITH CARE !
}





share|improve this answer





















  • I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
    – MTCoster
    Nov 12 at 17:52










  • @MTCoster your call, you could ... the message is misleading ...
    – Titian Cernicova-Dragomir
    Nov 12 at 17:54






  • 2




    It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
    – MTCoster
    Nov 12 at 18:08













up vote
1
down vote



accepted







up vote
1
down vote



accepted






The problem is that I might have other required properties in addition to param. Typescript will force your generic function implementation to return a valid value for any I that satisfies the constraint of extending IExample<U>, and it does not.



For example:



interface DerivedIExample extends IExample<number> {
other : string
}
let o = testFunc<number, DerivedIExample>(0)
o.other // required by the DerivedIExample but not assigned


In your simple example, it would be best to do away with I completely:



function testFunc<U>(myParam: U): IExample<U> {
return { param: myParam };
}


You can force the compiler to accept your code using a type assertion but as outlined above that is not type-safe:



function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam } as I; // NOT TYPE SAFE! USE WITH CARE !
}





share|improve this answer












The problem is that I might have other required properties in addition to param. Typescript will force your generic function implementation to return a valid value for any I that satisfies the constraint of extending IExample<U>, and it does not.



For example:



interface DerivedIExample extends IExample<number> {
other : string
}
let o = testFunc<number, DerivedIExample>(0)
o.other // required by the DerivedIExample but not assigned


In your simple example, it would be best to do away with I completely:



function testFunc<U>(myParam: U): IExample<U> {
return { param: myParam };
}


You can force the compiler to accept your code using a type assertion but as outlined above that is not type-safe:



function testFunc<U, I extends IExample<U>>(myParam: U): I {
return { param: myParam } as I; // NOT TYPE SAFE! USE WITH CARE !
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 at 17:38









Titian Cernicova-Dragomir

51.5k33148




51.5k33148












  • I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
    – MTCoster
    Nov 12 at 17:52










  • @MTCoster your call, you could ... the message is misleading ...
    – Titian Cernicova-Dragomir
    Nov 12 at 17:54






  • 2




    It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
    – MTCoster
    Nov 12 at 18:08


















  • I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
    – MTCoster
    Nov 12 at 17:52










  • @MTCoster your call, you could ... the message is misleading ...
    – Titian Cernicova-Dragomir
    Nov 12 at 17:54






  • 2




    It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
    – MTCoster
    Nov 12 at 18:08
















I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
– MTCoster
Nov 12 at 17:52




I don’t know why I didn’t just eliminate I in the first place, thanks! Is it worth opening an issue to note the unhelpful(/misleading?) error message?
– MTCoster
Nov 12 at 17:52












@MTCoster your call, you could ... the message is misleading ...
– Titian Cernicova-Dragomir
Nov 12 at 17:54




@MTCoster your call, you could ... the message is misleading ...
– Titian Cernicova-Dragomir
Nov 12 at 17:54




2




2




It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
– MTCoster
Nov 12 at 18:08




It turns out the error has already been fixed in the nightly builds, it’s now: Type '{ param: U; }' is not assignable to type 'I'.
– MTCoster
Nov 12 at 18:08


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53267269%2ftypescript-generic-interface-parameter-assignment%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

How to send String Array data to Server using php in android

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

Is anime1.com a legal site for watching anime?