我正在try 获取普通级联类型的子密钥.


type Cascade<C extends string, T extends Cascade<C, T>> = Partial<
  Record<C, T[]>
>

/**
 * {
 *   name: 'x',
 *   code: 'x',
 *   childGeoList: [{name: 'y', code: 'y'}]....
 * }
 */
interface AreaItem extends Cascade<'childGeoList', AreaItem> {
  name: string
  code: Number
}

type ChildKey = AreaItem extends Cascade<infer K, infer _> ? K : never

// ?为什么A不是" children 地理列表"?
// 修复它并让ChildKey等于‘ChildGeoList’?

?为什么A不是" children 地理列表"?

修复它并让ChildKey等于‘ChildGeoList’?

推荐答案

不幸的是,TS的推理能力无法做到这一点.在事先不知道K_是什么的情况下,类型Cascade<K, _>似乎太宽,编译器无法推断出任何有用的东西.

我的建议是对密钥进行更显式的计算,如下所示:

type ChildKey<C extends Record<string, any>> =
    keyof { [K in keyof C as C[K] extends C[] | undefined ? K : never]: any };

在这里,您只需要寻找其值可能是未定义的C数组的任何C键.对于AreaItem,这将按预期工作:

type AreaItemChildKey = ChildKey<AreaItem>
// type AreaItemChildKey = "childGeoList"

如果你有其他妨碍你的属性,它可能会产生令人惊讶的结果:

interface Oops extends Cascade<'x', Oops> {
    name: string;
    hello: Oops[]
}
type OopsChildKey = ChildKey<Oops>
// type OopsChildKey = "x" | "hello"

这可能不是你想要的,但structurally美元与

interface Oops2 extends Cascade<'x' | 'hello', Oops2> {
    name: string;
}
type Oops2ChildKey = ChildKey<Oops2>
// type OopsChildKey = "x" | "hello"

因此,在那里没有什么可做的.

Playground link to code

Typescript相关问答推荐

错误:note_modules/@types/note/globals.d.ts:72:13 -错误TS 2403:后续变量声明必须具有相同的类型

使用新控制流的FormArray内部的Angular FormGroup

如何使用axios在前端显示错误体

如何在方法中定义TypeScript返回类型,以根据参数化类型推断变量的存在?

如果在TypeScript中一个原始的类方法是递归的,如何使用类decorator 模式?

使用Angular和API请求在CRUD操作后更新客户端数据的良好实践

如何使类型只能有来自另一个类型的键,但键可以有一个新值,新键应该抛出一个错误

接口的额外属性作为同一接口的方法的参数类型'

基于平台的重定向,Angular 为16

如何正确地对类型脚本泛型进行限制

根据上一个参数值查找参数类型,也返回类型

CDK从可选的Lambda角色属性承担角色/复合主体中没有非空断言

TypeError:正文不可用-NextJS服务器操作POST

如何在ANGLE中注册自定义验证器

API文件夹内的工作员getAuth()帮助器返回:{UserID:空}

与toast.error一起react 中的Async TUNK错误消息

我不明白使用打字脚本在模板中展开参考

为什么我的函数arg得到类型为Never?

如何以类型安全的方式指定键的常量列表,并从该列表派生所挑选的接口?

Typescript 确保通用对象不包含属性