我对打字稿中的省略类型有疑问,所以我知道省略类型与Pick
相对,其构建方式如下:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
但是我不知道如何构造一个Omit类型。我有一个Student
的界面,看起来像这样:
interface Student {
name: string,
surname: string,
age: number,
email: string
}
我需要一个函数,该函数将Student作为具有某些给定属性的输入,并输出被忽略的Student。该函数应如下所示:
let omit_student = <K extends keyof Student>(student: Student, ...props: K[] ): Omit<Student, K> => null!
但是我不知道如何动态地省略Student的给定属性以及该函数的主体中应该发生什么。
这样调用函数:omit_student(student1, "name", "age")
应该输出以下类型:
{
surname: string,
email: string
}
答案 0 :(得分:0)
要声明Omit
类型,请使用CRice的答案:
interface Student {
name: string,
surname: string,
age: number,
email: string
}
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
let student: Student = { name: "John", surname: "Doe", age: 21, email: "John.Doe@test.com" }
let omit_student: Omit<Student, "name" | "age"> = student
这将创建仅包含surname
和email
的新类型。但是,这只会在编译时抱怨(使用surname
或email
以外的其他属性时),您必须自己编写一个过滤器方法以符合用Omit
描述的接口。 / p>
function omitStudent(student: Student, ...args: string[]): Omit<Student, "name" | "age"> {
for (let key of args) {
delete student[key]
}
return student
}
console.log(student);
console.log(omitStudent(student, "name", "age"));
尽管我意识到这可能不像您在问题中所问的那样“动态”。
答案 1 :(得分:0)
常见的混淆原因是TypeScript中的对象类型不是exact。众所周知,类型为Student
的值具有适当类型的name
,surname
,age
和email
属性,但不知道只有 这些属性。这样,您可以通过向它们添加已知的属性来extend种类型:
interface Student {
name: string,
surname: string,
age: number,
email: string
}
interface HogwartsStudent extends Student {
house: string,
spells: string[]
}
在上面,HogwartsStudent
是Student
的特殊类型。如果我给您Student
,您可能不知道她不是HogwartsStudent
,所以您无法确定她没有house
或spells
属性。
Omit<T, K>
类型的别名产生T
的超类型。也就是说,T
扩展了Omit<T, K>
。类型T
的每个值也是类型Omit<T, K>
的值。您仅使用Omit<T, K>
来“忽略”的是K
中带有键的属性的已知存在和类型。
您要的不仅是从类型中删除已知键,而且要从生成的对象中删除实际属性。这需要在运行时以与JavaScript中完全相同的方式发生:
function omit_student<K extends Array<keyof Student>>(
student: Student, ...props: K): Omit<Student, K[number]> {
const newStudent: Omit<Student, K[number]> = Object.assign({}, student);
for (let prop of props) {
delete (newStudent as any)[prop];
}
return newStudent;
}
请注意,我为K
参数使用了rest tuple type,但是您也可以按照自己的方式进行操作。
希望有帮助。祝你好运!