最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - Why my constrained generic type in conjunction with a conditional type doesn't work as expected? - Stack Ov

programmeradmin0浏览0评论

The following Typescript code snippet produces an error

function importedF<R extends string>(a: R extends string ? number : never) {}

function genericF<T extends string>() {
  importedF<T>(1);
}

where the error is on the parameter 1 passed to importedF and reads

Argument of type 'number' is not assignable to parameter of type 'T extends string ? number : never'.ts(2345)

Please help me understand why Typescript doesn't understand that T is indeed a string and thus the conditional statement should result in number. I'm looking for understanding rather than workaround.

The following Typescript code snippet produces an error

function importedF<R extends string>(a: R extends string ? number : never) {}

function genericF<T extends string>() {
  importedF<T>(1);
}

where the error is on the parameter 1 passed to importedF and reads

Argument of type 'number' is not assignable to parameter of type 'T extends string ? number : never'.ts(2345)

Please help me understand why Typescript doesn't understand that T is indeed a string and thus the conditional statement should result in number. I'm looking for understanding rather than workaround.

Share Improve this question edited Mar 26 at 19:52 Rubinous asked Feb 28 at 20:20 RubinousRubinous 4866 silver badges14 bronze badges 4
  • 1 What's the question exactly, is it "why is this happening"? Then it's ms/TS#51523 and issues linked within. If it's "how do I fix this", well, it's a TS design limitation, and the right thing to do is fix importedF. If you can't do that, then use a type assertion or something non-generic like this playground link. Please edit to clarify your primary question (it really can't be "both" because then you invite multiple answers), and let me know how you'd like to proceed. – jcalz Commented Feb 28 at 20:34
  • @jcalz, my question was indeed "why is this happening" but I assumed that I was misunderstanding something and needed to be educated. So knowing that it's an issue with the Typescript implementation is enough for me and I'll work my way around it. – Rubinous Commented Mar 18 at 10:35
  • 1 Great, then could you please edit the question to make that explicit and I'll add an answer pointing to the relevant github issues? – jcalz Commented Mar 18 at 13:46
  • Done! Hope it's clearer now. – Rubinous Commented Mar 26 at 19:54
Add a comment  | 

2 Answers 2

Reset to default 1

This is considered a design limitation of TypeScript, as described at microsoft/TypeScript#51523 and issues linked within.

If you have a conditional type that depends on a generic type parameter, TypeScript mostly just defers evaluation of it. Inside genericF(), T is generic, and TypeScript doesn't know exactly what it is yet, so the relevant type T extends string ? number : never is deferred. TypeScript doesn't even try to evaluate it. You might hope that because T has a constraint TypeScript could use it to partially (or wholly) evaluate the type instead of deferring it, but that doesn't happen. So TypeScript doesn't know what might be assignable to T extends string ? number : never, and it complains about 1.

As mentioned in the comments TS doesnt handle well conditional types with generics, you could overload the function. Also it's not clear why you need the conditional type, since R always a string. Given that R could be also any:

Playground

function importedF<R extends string>(a: number): void;
function importedF<R extends any>(a: never): void;
function importedF(a: number):void {

}

function genericF<T extends string>() {
  importedF<T>(1);
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论