如何从类型中省略属性? [英] How to Omit a property from a type?

查看:24
本文介绍了如何从类型中省略属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Typescript 中的 Omit 类型有疑问,所以我知道 Omit 类型与 Pick 是相反的,并且是这样构建的:

I have a question about the Omit type in Typescript, so I know the Omit type is the opposite of Pick and is build like this:

type Omit= Pick

但是我不知道如何构造一个 Omit 类型.我有一个 Student 的界面,如下所示:

But I don't know how to construct a Omit type. I have an interface of Student that looks like this:

interface Student { 
name: string, 
surname: string, 
age: number, 
email: string 
}

我需要一个函数,该函数将学生作为具有某些给定属性的输入并输出省略的学生.该函数应如下所示:

I need a function that takes a Student as input with some given properties and outputs the Omited Student. The function should look like this:

let omit_student = (student: Student, ...props: K[] ): Omit=>null!

但我不知道如何从 Student 动态省略给定的属性以及函数体中应该发生什么.

But I don't know how I can dynamicaly omit the given properties from Student and what should happen in the body of the funtion.

像这样调用函数:omit_student(student1, "name", "age")应该输出以下类型:

Calling the function like this: omit_student(student1, "name", "age") should output the following type:

{ 
surname: string, 
email: string 
}

推荐答案

TypeScript 中的对象类型不是 准确.Student 类型的值已知具有namesurnameage、和 email 属性的适当类型,但不知道只有这些属性.这允许您通过向类型添加已知属性来扩展类型:

It is a common source on confusion that object types in TypeScript are not exact. A value of type Student is known to have name, surname, age, and email properties of the appropriate types, but it is not known to have only these properties. This allows you to extend types by adding known properties to them:

interface Student { 
    name: string, 
    surname: string, 
    age: number, 
    email: string 
}

interface HogwartsStudent extends Student {
    house: string,
    spells: string[]
}

在上面,HogwartsStudent 是一种特殊类型的 Student.如果我给你一个Student,你不知道她不是一个HogwartsStudent,所以你不能确定她有没有 housespells 属性.

In the above, a HogwartsStudent is a special type of Student. If I give you a Student, you don't know that she is not a HogwartsStudent, so you can't be sure that she has no house or spells property.

Omit 类型别名产生T超类型.也就是说,T 扩展了 Omit.T 类型的每个值也是 Omit 类型的值.您在 Omit 中省略"的只是K 中带有键的属性的已知存在和类型.

The Omit<T, K> type alias produces a supertype of T. That is, T extends Omit<T, K>. Every value of type T is also a value of type Omit<T, K>. All you are "omitting" with Omit<T, K> is the known presence and type of properties with keys in K.

您要求的不仅是从类型中删除已知键,而且是从生成的对象中删除实际属性.这需要在运行时以与在 JavaScript 中完全相同的方式发生:

What you are asking for is not only to remove the known keys from the type, but to remove the actual properties from the produced object. This needs to happen at runtime in exactly the way you'd do it in 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;
}

请注意,我使用了 rest tuple type 用于 K 参数,但您也可以按照自己的方式进行操作.

Notice that I've used a rest tuple type for the K parameter, but you can probably do it your way also.

希望有所帮助.祝你好运!

Hope that helps. Good luck!

这篇关于如何从类型中省略属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆