我是相对较新的 typescript ,并有什么我认为是一个奇怪的错误。
我有多个对象使用send data到服务器,然后从服务器返回同一对象的新数据。不同的对象使用相同的方法发送数据,所以我使用union
来指定方法可以接受这两种类型中的任何一种,但是我得到了一个错误。
我已经制作了一个简单版本的代码来复制这个问题,我可以做到。
type A = {
aField: string;
aaField: string;
}
type B = {
bField: string;
bbField: number
}
type Student = A | B;
type Func = (student: Student) => Student;
const test = {
aField: 'Test',
aaField: 'Test Again'
}
const funcA = (a: A): A => {
return a;
}
const funcB = (b: B): B => {
return b;
}
const func = (student: Student): Student => {
return student;
}
const component = (func: Func) => {
return func;
}
component(func);
component(funcA);
我得到的错误如下
类型'(a:A)=〉A'不能赋值给' Func'类型的参数。
参数“a”和“student”的类型不兼容。
类型“Student”不能赋值给类型“A”。
类型“B”缺少类型“A”的以下属性:a字段,aa字段
有没有一种方法可以绕过这个问题,而不必强制转换每个函数的类型?
2条答案
按热度按时间af7jpaap1#
可以使用分布条件类型将
Student
联合分布到匹配的函数签名上:这里有一个完整的片段操场链接。
rqqzpn5f2#
当用于输入 callback 参数(如
component
函数的func
参数)时,联合类型的约束比您想象的要大。当我们有:
......我们说
Func
* 必须 * 接受Student
类型的参数,它可以是(在 * 调用者意愿 * 下)A
或B
。这就是你的
func
函数所做的,但 * 不是 *funcA
或funcB
,如果我们尝试将它们输入为Func
,就可以看到这一点:Playground链接
funcA
和funcB
分别接受A
和B
,但不接受并集A | B
(funcA
不接受B
,反之亦然),因此它们不匹配Func
。我有多个对象,它们使用向服务器发送数据,然后从服务器返回同一对象的新数据。
根据您的描述,您更需要一个generic类型参数,它也为回调返回提供相同的类型:
对于
T extends A | B
泛型类型,我们假设func
回调函数必须接受T
类型的参数,该参数可 * 赋值 * 给A | B
,因此A
或B
都可以(不一定同时)。此外,我们还指定
T
为返回类型,因此如果传递的回调函数接受A
,它也会返回A
类型(对于B
也是如此),与您的描述相匹配。Playground链接