【问题标题】:Omit properties with of certain types in TypeScript在 TypeScript 中省略某些类型的属性
【发布时间】:2021-07-06 11:13:24
【问题描述】:

我正在为学校做一个简单的项目。我想知道是否可以在 TypeScript 中省略某些类型的所有属性。

type Student = {
    firstName: string
    lastName: string
    age: number
    gender: Gender
    courses: List<Course>
}

所以在这种情况下,我只想要一个包含 Student 的所有内容的类型,而没有 "courses"

是否可以生成一个类型,它是 Student,但没有具有 List 类型的所有属性?它需要是通用的,因此它适用于所有类型,例如:

type Program = {
    name: string
    errors: List<Error>
    successes: List<Success>
    warnings: List<Warning>
}

现在它会给出一个只包含 { name: string }

的类型

如果可能的话,有谁知道如何做到这一点?也许有条件类型?如果列表省略?

非常感谢所有帮助!

更新:添加代码示例:

type WithoutList<T> = {
    [K in keyof T]: T[K] extends List<any> ? never : T[K]
}

const select = <a, b extends keyof WithoutList<a>>(arg: a, ...keys: b[]) => {
    return null!
}

const s1: Student = {
    firstName: 's',
    lastName: 's',
    age: 22,
    gender: 'female',
    courses: List<Course>(),
}

select(s1, 'courses') // courses should not be available here!

【问题讨论】:

  • type OmitLists&lt;T&gt; = { [P in keyof T]: T[P] extends List&lt;any&gt; ? never : T[P] };

标签: typescript types typescript-typings typescript-generics


【解决方案1】:

您可以使用key remapping in mapped types 将您想要抑制的所有 映射到never

type WithoutList<T> = {
  [K in keyof T as T[K] extends List<any> ? never : K]: T[K]
};

您可以验证这适用于您示例中的 StudentProgram 类型:

type StudentWithoutList = WithoutList<Student>;
/* type StudentWithoutList = {
    firstName: string;
    lastName: string;
    age: number;
    gender: Gender;
} */

type ProgramWithoutList = WithoutList<Program>;
/* type ProgramWithoutList = {
    name: string;
} */

以及您的 select() 函数所需的行为:

declare const s1: Student;
select(s1, "age"); // okay
select(s1, 'courses') // error!

Playground link to code

【讨论】:

  • 该死!这对我有用,谢谢大佬!我仍然需要练习很多我看到的,但我从你的回答中学到了很多东西!
【解决方案2】:

mapped type 与当类型扩展 List 时计算结果为 never 的条件类型相结合将得到您想要的。

由于您的代码中没有定义 GenderListCourse,因此我将使用 Array 和原始类型来进行说明:

type Student = {
    firstName: string
    lastName: string
    age: number
    courses: Array<string>
}

type WithoutList<T> = {
    [K in keyof T]: T[K] extends Array<any> ? never : T[K]
}

type StudentWithoutCourse = WithoutList<Student>;

Demo

【讨论】:

  • 这不是我的意思。我将在我的问题中添加一些代码。使用选择方法。它应该可以访问除课程之外的所有内容。但是对于您的自定义类型,它仍然是您可以选择的属性。
猜你喜欢
  • 1970-01-01
  • 2022-06-24
  • 1970-01-01
  • 2019-09-06
  • 2020-09-12
  • 1970-01-01
  • 2020-09-21
  • 2021-09-16
  • 2019-05-26
相关资源
最近更新 更多