我有一个预定义的复杂接口,我不能操纵它,因为它来自第三方库.

interface Fruit {
    name?: string;
    id?: number;
    weight?: number;
}

我需要

  • 定义该接口的键的子集的列表,然后
  • 定义一个新接口(或类型),它将只包含那些^成员,其类型将与原始接口相同.

To clarify: 我需要 actually use the list in my code (otherwise I would just write them into a Pick<Fruit, ...> and be done with it).

以下是一种方法:

const fieldsToIsolate = ["id", "weight"] as const;

type IsolatedFruit = Pick<Fruit, typeof fieldsToIsolate[number]>;
// type IsolatedFruit = {
//     id?: number | undefined;
//     weight?: number | undefined;
// }

这种方法的问题是fieldsToIsolate不是类型安全的.

这里有一个不同的方法可以解决这个问题,但有自己的问题:

const fieldsToIsolate: Array<keyof Fruit> = ["id", "weight"];

type IsolatedFruit = Pick<Fruit, typeof fieldsToIsolate[number]>;
// type IsolatedFruit = {
//     name?: string | undefined;
//     id?: number | undefined;
//     weight?: number | undefined;
// }

现在,名单已经安全地输入了,但IsolatedFruit并不准确.

如果我们try 重新附加as const,则TypeScrip现在会出现问题,因为

The type 'readonly ["id", "weight"]' is 'readonly' and cannot be assigned to the mutable type '(keyof Fruit)[]'

有没有办法实现这一点?

推荐答案

我会用satisfies关键字做到这一点,这个关键字是在typescript 4.9年引入的:

const fieldsToIsolate = ["id", "weight"] satisfies Array<keyof Fruit>;

type IsolatedFruit = Pick<Fruit, typeof fieldsToIsolate[number]>;

这会导致TypeScrip做两件事:

  1. 根据您使用的精确值,fieldsToIsolate将获得比string[]更具体的类型.在本例中,类型将为('id' | 'weight')[].这反过来又允许IsolatedFruit成为正确的类型.
  2. TypeScrip将判断以验证"id"和"weight"是否确实是Fruit的键,如果不是,则会给出错误.因此,打字错误和不存在的键将引起您的注意.

Playground link

Typescript相关问答推荐

无法从应用程序内的库导入组件NX Expo React Native

如何在使用`Next—intl`和`next/link`时导航

如何缩小变量访问的对象属性范围?

迁移到Reaction路由V6时,获取模块Reaction-Router-Dom';没有导出的成员RouteComponentProps错误

如何在Typescript 中输入两个相互关联的变量?

为什么不能使用$EVENT接收字符串数组?

Angular 17子路由

有什么方法可以类型安全地包装import()函数吗?

有没有办法防止类型交集绕过联合类型限制?

如何获取受类型脚本泛型约束的有效输入参数

带投掷的收窄类型

TypeScrip:如何缩小具有联合类型属性的对象

在打印脚本中将对象类型转换为数组

使用RXJS获取数据的3种不同REST API

有没有一种方法可以提升对象的泛型级别,而对象的值是泛型函数?

可以用任意类型实例化,该类型可能与

Typescript 从泛型推断类型

如何通过nx找到所有受影响的项目?

如何按成员资格排除或 Select 元组?

在 TypeScript 中实现类型级别深度优先搜索