打字稿:扩展多种类型的模板化接口数组
typescript: Array of templated interface extending multiple types
这是我的问题的一个最小示例
interface Dog {
legs: number;
}
interface Person {
arms: number;
}
type Living = Person | Dog;
interface Speaker<T extends Living> {
speak: (living: T) => void;
};
const michel: Speaker<Person> = { speak: (person) => console.log(`I have ${person.arms} arms`) };
const speakers: Array<Speaker<Living>> = [michel];
它抛出这个错误
Type 'Speaker<Person>' is not assignable to type 'Speaker<Living>'.
Type 'Living' is not assignable to type 'Person'.
Property 'harms' is missing in type 'Dog' but required in type 'Person'
我想要一个 Speaker
的数组,它接受任何类型的 Living
。
感谢您的宝贵时间!
按照您定义事物的方式,Speaker<Living>
表示一个对象具有一个以 Person | Dog
作为参数的 speak 函数。当你创建 michel
时,你有以下函数,如果给定一个 Person
:
就可以正常工作
(person) => console.log(`I have ${person.arms} arms`)
但是如果给定一个 Person | Dog
它就不会工作,因为它试图访问一只狗的 .arms
属性。这种不匹配和其他原因是打字稿告诉您 Speaker<Person>
不能分配给 Speaker<Living>
的原因
如果你希望数组是对象的混合体,其中一些需要 Person
s 作为它们的 speak 函数,其中一些需要 Dog
s,那么它的类型将是:
const speakers: Array<Speaker<Person> | Speaker<Dog>> = [michel];
编辑:如果你的 Living
union 很大,或者你希望扬声器在更多类型添加到 Living
时自动更新,那么你可以使用以下获取打字稿来生成 Speaker<Person> | Speaker<Dog>
联合给你:
type Distribute<T> = T extends Living ? Speaker<T> : never;
const speakers: Array<Distribute<Living>> = [michel];
// speakers is of type Array<Speaker<Person> | Speaker<Dog>>
这是我的问题的一个最小示例
interface Dog {
legs: number;
}
interface Person {
arms: number;
}
type Living = Person | Dog;
interface Speaker<T extends Living> {
speak: (living: T) => void;
};
const michel: Speaker<Person> = { speak: (person) => console.log(`I have ${person.arms} arms`) };
const speakers: Array<Speaker<Living>> = [michel];
它抛出这个错误
Type 'Speaker<Person>' is not assignable to type 'Speaker<Living>'.
Type 'Living' is not assignable to type 'Person'.
Property 'harms' is missing in type 'Dog' but required in type 'Person'
我想要一个 Speaker
的数组,它接受任何类型的 Living
。
感谢您的宝贵时间!
按照您定义事物的方式,Speaker<Living>
表示一个对象具有一个以 Person | Dog
作为参数的 speak 函数。当你创建 michel
时,你有以下函数,如果给定一个 Person
:
(person) => console.log(`I have ${person.arms} arms`)
但是如果给定一个 Person | Dog
它就不会工作,因为它试图访问一只狗的 .arms
属性。这种不匹配和其他原因是打字稿告诉您 Speaker<Person>
不能分配给 Speaker<Living>
如果你希望数组是对象的混合体,其中一些需要 Person
s 作为它们的 speak 函数,其中一些需要 Dog
s,那么它的类型将是:
const speakers: Array<Speaker<Person> | Speaker<Dog>> = [michel];
编辑:如果你的 Living
union 很大,或者你希望扬声器在更多类型添加到 Living
时自动更新,那么你可以使用以下获取打字稿来生成 Speaker<Person> | Speaker<Dog>
联合给你:
type Distribute<T> = T extends Living ? Speaker<T> : never;
const speakers: Array<Distribute<Living>> = [michel];
// speakers is of type Array<Speaker<Person> | Speaker<Dog>>