是否可以使用打字稿进行类似的操作,重命名属性名称或其他名称?
interface Person {
name: string
age: number
}
interface Pet {
age: string
}
interface Zoo extends Pet, Person {}
没有收到此错误:
接口“ Zoo”不能同时扩展类型“ Person”和“ Pet” 类型“人”和“宠物”的命名属性“年龄”不同。ts(2320)
[编辑]
我正在寻找一种获得此结果的方法:
interface Zoo {
name: string
age: number
}
答案 0 :(得分:1)
啊,所以您不是要重命名属性。只需从接口之一中删除任何冲突的属性。
这与object spread type operator的概念非常相似,TypeScript在类型级别上目前还不属于该语言的一部分。当前,类型系统将通用扩展名视为intersection,这仅适用于不冲突的属性。)在值/表达式级别,TypeScript会正确处理具体类型的扩展名,因此您可以获得特定的{{ 1}}通过说服类型系统来寻找您具有Zoo
类型的值,Pet
类型的值以及通过散布它们而形成的值:
Person
如果您不想随意使用值(特别是如果您无处闲逛),并且只想在类型级别上执行此操作,则可以使用{ {3}}和mapped类型。一位语言设计师建议使用interface Person {
name: string
age: number
}
interface Pet {
age: string
trained: boolean // I added this because otherwise Zoo=Person which is weird
}
declare const person: Person; // pretend we have a person
declare const pet: Pet; // pretend we have a pet
const zoo = { ...pet, ...person }; // spread them into a new variable
type ZooType = typeof zoo; // get the type of that variable
// type ZooType = {
// name: string;
// age: number;
// trained: boolean;
// }
interface Zoo extends ZooType { }; // make it an interface because why not
中的conditional,在围绕可选/只读/等属性的一些注意事项方面可以很好地发挥作用。
对于您来说,由于没有可选属性或只读属性,因此这是一个更简单的实现,我将其称为Spread<L,R>
:
Merge<L, R>
您会看到它的行为类似于上述价值水平价差:
type Merge<L, R> = R & Pick<L, Exclude<keyof L, keyof R>>;
注意事项:如果interface Zoo extends Merge<Pet, Person> { };
declare const zoo: Zoo;
zoo.name; // string
zoo.age; // number
zoo.trained; // boolean
在age
中为可选,则Person
将使Merge<Pet, Person>
在age
中为可选。 可能是您想要的,但是价差不会以这种方式表现; Zoo
始终需要一个{...pet, ...person}
,因为age
需要一个。这样一来,Pet
类似于Zoo["age"]
,上面链接的string | number
运算符将更正确地处理。同样,Spread<L, R>
和链接的Merge<>
都不能保证通过Spread<>
属性来做“正确的事情”,特别是因为我不清楚那是正确的事情。
好的,希望能有所帮助。祝你好运!