我希望对接口中的嵌套属性执行类型判断,并具有以下代码

type PathImpl<T, K extends keyof T> = K extends string
  ? T[K] extends Record<string, any>
    ? `${K}.${Path<T[K]>}` | K
    : K
  : never;

export type Path<T> = PathImpl<T, keyof T>;

export interface User {
  name: string;
  age: number;
  dimensions: {
    height: number;
    weight: number;  
  }
  address?: {
    street: string;
    city: string;
    state: string;
  };
}

const validPath: Path<User> = 'name'; // Works fine
const alsoValidPath: Path<User> = 'address'; // Works fine
const nestedValidPath: Path<User> = 'dimensions.height'; // Yay, works fine!
const doesntWorkPath: Path<User> = 'address.street'; // Doesn't work because address is optional

有没有一种方法可以设计Path类型来允许"address.street"也是有效的,尽管address是可选的?

Playground link

推荐答案

您可以使用Path中的Required实用程序类型根据需要标记输入类型的所有属性:

export type Path<T> = PathImpl<Required<T>, keyof T>;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^

那么你最后的"address.street"的作业(job)是有效的,因为Path<User>的类型是:

| "name" 
| "age" 
| "dimensions" 
| "address" 
| "dimensions.height" 
| "dimensions.weight" 
| "address.street" 
| "address.city" 
| "address.state"

Playground link

Typescript相关问答推荐

如何传递基于TypScript中可变类型的类型?

为什么缩小封闭内部不适用于属性对象,但适用于声明的变量?

在Angular中注入多个BrowserModules,但在我的代码中只有一个

如何在TypeScrip面向对象程序设计中用方法/属性有条件地扩展类

Angular 错误NG0303在Angular 项目中使用app.Component.html中的NGFor

TypeScrip原始字符串没有方法

访问继承接口的属性时在html中出错.角形

如何使用Geojson模块和@Types/Geojson类型解析TypeScrip中的GeoJSON?

如何在NX工作区项目.json中设置类似angular.json的两个项目构建配置?

如何从对象或类动态生成类型

创建一个TypeScrip对象并基于来自输入对象的约束定义其类型

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

Rxjs将省略的可观测对象合并到一个数组中

递归类型别名的Typescript 使用

换行TypeScript';s具有泛型类型的推断数据类型

通过函数传递确切的类型,但验证额外的字段

记录的子类型<;字符串,X>;没有索引签名

Karma Angular Unit测试如何创建未解析的promise并在单个测试中解决它,以判断当时的代码是否只在解决后运行

当受其他参数限制时,通用参数类型不会缩小

是否有解释为什么默认情况下在泛型类型上访问的属性不是索引访问