类型不能分配给条件类型 [英] Type is not assignable to conditional type
问题描述
我在操场上有一个TypeScript代码段.请看看那里打字稿游乐场或此处:
枚举MyTypes {FIRST ="FIRST",SECOND ="SECOND",第三=第三"}输入TFirst = {类型:MyTypes.FIRSTfoo:字串}类型TSecond = {类型:MyTypes.SECONDfoo:字串}类型TThird = {类型:MyTypes.THIRD条:字符串}类型TConditionalType< T>=T扩展MyTypes.FIRST吗?TFirst:T扩展了MyTypes.SECOND吗?TSecond:T扩展MyTypes.THIRD吗?第三:空值const getMyObjectBasedOnType =< T扩展MyTypes>(类型:T):TConditionalType< T>|null =>{开关(类型){大小写MyTypes.FIRST:{返回 {类型:MyTypes.FIRST,foo:测试"}}默认: {返回null}}}const firstObject = getMyObjectBasedOnType(MyTypes.FIRST)//firstObject是TFirst的类型或可以为null的类型如果(firstObject){firstObject.foo}
有一个函数 getMyObjectBasedOnType(type:T)
,该函数根据 type
参数返回条件类型的对象.这似乎可行,因为末尾的 firstObject
类型为 TFirst |.空
.全部清除在这里.
我返回对象时,第31行中提到的函数内部存在TypeScript错误,这是我遇到的问题.我得到这个: Type'{type:MyTypes.FIRST;foo:字串;}"不能分配给"TConditionalType< T>"类型.
我无法弄清楚出了什么问题.据我了解,这是 TFirst
的对象,应该没问题.为什么我会收到此错误?什么是正确的解决方法?
关于您的问题,它来自于延迟的条件类型.查看打字稿文档: https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types .(推迟搜索条件类型
以到达页面的正确位置.)
有关此设计决策的简短讨论: https://github.com/Microsoft/TypeScript/issues/29939 ..>
最简单的解决方案是使用一个更宽松的单独实现签名,同时将公共签名保留为对调用者更有利的条件类型:
type TConditionalType< T>=T扩展MyTypes.FIRST吗?TFirst:T扩展了MyTypes.SECOND吗?TSecond:T扩展MyTypes.THIRD吗?第三:空值函数getMyObjectBasedOnType< T扩展了MyTypes>(类型:T):TConditionalType< T> ;;函数getMyObjectBasedOnType(type:MyTypes):TFirst |TSecond |TThird |空值 {开关(类型){大小写MyTypes.FIRST:{返回 {类型:MyTypes.FIRST,foo:测试"};//这里没有错}大小写MyTypes.SECOND:{返回 {类型:MyTypes.FIRST,foo:测试"};//不幸的是它将起作用...实现是允许的}默认: {返回null;}}}const firstObject = getMyObjectBasedOnType(MyTypes.FIRST)如果(firstObject){firstObject.foo;//它会工作firstObject.bar;//它将失败}
我仍在弄清楚如何使其与箭头功能配合使用.要了解这两者之间的区别,您可以在这里参考:正确使用用于在JavaScript中定义函数的const的说明
I have a TypeScript code snippet in the playground. Please take a look there at TypeScript playground or here:
enum MyTypes {
FIRST = "FIRST",
SECOND = "SECOND",
THIRD = "THIRD"
}
type TFirst = {
type: MyTypes.FIRST
foo: string
}
type TSecond = {
type: MyTypes.SECOND
foo: string
}
type TThird = {
type: MyTypes.THIRD
bar: string
}
type TConditionalType<T> =
T extends MyTypes.FIRST ? TFirst :
T extends MyTypes.SECOND ? TSecond :
T extends MyTypes.THIRD ? TThird :
null
const getMyObjectBasedOnType = <T extends MyTypes>(type: T): TConditionalType<T> | null => {
switch (type) {
case MyTypes.FIRST: {
return {
type: MyTypes.FIRST,
foo: 'test'
}
}
default: {
return null
}
}
}
const firstObject = getMyObjectBasedOnType(MyTypes.FIRST)
// firstObject is type of TFirst or null which is okay
if (firstObject) {
firstObject.foo
}
There is a function getMyObjectBasedOnType(type: T)
which returns an object of a conditional type based on the type
parameter. This seems to work since firstObject
at the end is of type TFirst | null
. All clear here.
Problem which I have is TypeScript error inside mentioned function on line 31 when I am returning object. I get this:
Type '{ type: MyTypes.FIRST; foo: string; }' is not assignable to type 'TConditionalType<T>'.
I can't figure it out what is wrong. As far as I understand it that is an object of TFirst
which should be okay. Why do I receive this error and what is proper fix for it?
Regarding your issue it comes from conditional types that are deferred. Look at the typescript documentation: https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types. (search for conditional types are deferred
to get to the right place in the page).
There were some brief discussions about this design decision: https://github.com/Microsoft/TypeScript/issues/29939.
The simplest solution is to use a separate implementation signature that is more permissive, while keeping the public signature with conditional types that is better for the caller:
type TConditionalType<T> =
T extends MyTypes.FIRST ? TFirst :
T extends MyTypes.SECOND ? TSecond :
T extends MyTypes.THIRD ? TThird :
null
function getMyObjectBasedOnType<T extends MyTypes>(type: T): TConditionalType<T>;
function getMyObjectBasedOnType(type: MyTypes): TFirst | TSecond | TThird | null {
switch (type) {
case MyTypes.FIRST: {
return {
type: MyTypes.FIRST,
foo: "test"
}; // nothing wrong here
}
case MyTypes.SECOND: {
return {
type: MyTypes.FIRST,
foo: "test"
}; // unfortunately it would work... The implementation is permissive
}
default: {
return null;
}
}
}
const firstObject = getMyObjectBasedOnType(MyTypes.FIRST)
if (firstObject) {
firstObject.foo; // it would work
firstObject.bar; // it would fail
}
I'm still figuring out how to make it works with arrow functions. To know the difference between those two you can refer here: Proper use of const for defining functions in JavaScript
这篇关于类型不能分配给条件类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!