gpt4 book ai didi

属于特定值属性的嵌套泛型类型的 typescript 字符串点表示法

转载 作者:行者123 更新时间:2023-12-05 03:20:30 25 4
gpt4 key购买 nike

这个问题是发现的问题的扩展 here .

我有一个对象:

type exampleType = {
propertyOne: string
propertyTwo: number,
propertyThree: {
propertyFour: string,
propertyFive: Date,
propertySix: boolean,
}
}

我正在寻找一种类型,它可以将类似字符串的点符号验证为 string 的路径。或 Date .在上面的示例中,这意味着类型编译为:

propertyOne | propertyThree.propertyFour | propertyThree.PropertyFive

使用上面先前提出的问题,以下是可能的:

type PathsToStringProps<T> = T extends string ? [] : {
[K in Extract<keyof T, string>]: [K, ...PathsToStringProps<T[K]>]
}[Extract<keyof T, string>];

type Join<T extends string[], D extends string> =
T extends [] ? never :
T extends [infer F] ? F :
T extends [infer F, ...infer R] ?
F extends string ?
`${F}${D}${Join<Extract<R, string[]>, D>}` : never : string;

type Path = Join<PathsToStringProps<exampleType>, ".">

我试图使上述解决方案通用,这样我就可以给出 Path两个通用参数:T , 代表 exampleType在这里,和V ,这将是 string|Date在我上面的例子中。

当我尝试制作 exampleType 时通用:

type Path<T> = Join<PathsToStringProps<T>, ".">

我收到此错误:Excessive stack depth comparing types 'PathsToStringProps<T>' and 'string[]'.ts(2321)

我能够通过指定 T 必须代表一个键值对象来解决这个问题:

type Path<T extends {[key: string]: any}> = Join<PathsToStringProps<T>, ".">

继续将值的类型限制为路径指向:

type PathsToStringProps<T, V> = T extends (V) ? [] : {
[K in Extract<keyof T, string>]: [K, ...PathsToStringProps<T[K], V>]
}[Extract<keyof T, string>];

type Join<T extends string[], D extends string> =
T extends [] ? never :
T extends [infer F] ? F :
T extends [infer F, ...infer R] ?
F extends string ?
`${F}${D}${Join<Extract<R, string[]>, D>}` : never : string;

type Path<T extends {[key: string]: any}, V> = Join<PathsToStringProps<T, V>, ".">

但是我得到一个错误:

error

如果我从 Path 中删除通用参数 V,它就会消失, 但保留在 PathsToStringProps 中:

type Path<T extends {[key: string]: any}> = Join<PathsToStringProps<T, string|Date>, ".">

Here's a TypeScript Playground of my final attempt at getting this to work.

最佳答案

您的方法,其中PathsToProps<T, V>生成路径为 tuples ,然后在哪里 Join<T, D>连接元组元素以形成虚线路径,对编译器来说是有问题的,因为 PathToProps<T, V>Join<T, D>recursive conditional types ,它们的组合并不总是很好,并且经常与循环守卫或性能问题发生冲突。也许您可以调整一些东西以使其正常工作,但这不是我的第一选择。

相反,由于您似乎根本不关心元组,您可以直接在 PathsToProps<T, V> 中连接字符串。 .换句话说,您不是先构建路径然后再连接它们,而是在整个过程中连接。

它可能看起来像这样:

type PathsToProps<T, V> = T extends V ? "" : {
[K in Extract<keyof T, string>]: Dot<K, PathsToProps<T[K], V>>
}[Extract<keyof T, string>];

type Dot<T extends string, U extends string> =
"" extends U ? T : `${T}.${U}`

执行PathsToProps与您的非常相似,除了不是显式处理空元组 []并通过 [K, ...PathsToProps<T[K], V>>] 添加到元组中,我们明确使用空字符串 ""并通过 Dot<K, PathsToProps<T[K], V> 连接它们.

Dot<T, U> type 只是连接字符串的简写 T用一个已经点缀的字符串 U .除非U,否则你在它们之间加一个点是空的(如果你有任何对象以空字符串作为键,这在技术上是错误的。你没有,是吗?我希望不是)。关键是要确保您不会以需要删除的尾随点结束(如果您总是用点连接,那么您会得到类似 "foo.bar.baz." 的路径)。

让我们测试一下:

type ExampleType = {
propertyOne: string
propertyTwo: number,
propertyThree: {
propertyFour: string,
propertyFive: Date,
propertySix: boolean,
}
}

type StrOrDateEx = PathsToProps<ExampleType, string | Date>
// type StrOrDateEx = "propertyOne" | "propertyThree.propertyFour" |
// "propertyThree.propertyFive"

看起来不错!并且没有递归警告。

Playground link to code

关于属于特定值属性的嵌套泛型类型的 typescript 字符串点表示法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73159893/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com