当 TypeScript 4.1 登陆时,您将能够通过以下方式操作字符串文字类型模板文字类型如实施于微软/TypeScript#40336 https://github.com/microsoft/TypeScript/pull/40336。以下是一种可能的实现,用于将类型转换为斜杠分隔路径的联合,从而导致非对象属性:
type Join<K, P> = K extends string | number ?
P extends string | number ?
`${K}${"" extends P ? "" : "/"}${P}`
: never : never;
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]]
type Leaves<T, D extends number = 10> = [D] extends [never] ? never : T extends object ?
{ [K in keyof T]-?: Join<K, Leaves<T[K], Prev[D]>> }[keyof T] : "";
我在这里放置了显式递归限制器,所以如果您尝试这样做Leaves<SomeTreelikeType>
您可以选择最大深度。如果你不在乎你就会忘记Prev
and D
并且只是有
type Leaves<T> = T extends object ?
{ [K in keyof T]-?: Join<K, Leaves<T[K]>> }[keyof T] : "";
这为您提供了您想要的联盟:
type ComputedUnionType = Leaves<typeof something>;
// type ComputedUnionType = "topProp" | "foo/bar/str" | "foo/bar/num" | "some/prop"
你的部分didn't问的是如何让编译器将路径的类型转换为结果输出的类型。这也是可能的(与#40002 中实现的递归条件类型 https://github.com/microsoft/TypeScript/pull/40002,也登陆 TS4.1),但既然你没有问,我不会花时间实现它。
Playground 代码链接 https://www.typescriptlang.org/play?ts=4.1.0-dev.20200921#code/LAKALgngDgpgBAKQPYEsB2AeA0gGjgBQD44BeOLOGADzBjQBMBnORsAJ3QHM4AfONAK4BbAEYw2cAPyg4BSjTpMW7Lr37CxE6SFkADACQBvLAF8jAInPzaDZvilxLcAFyOA9ObOH8J3TJf8MABu4gFoweIA3KCgkLAEbMGkcADa4SFseAAMeACMeABMeADMeAAseACseABseADseAAceACceTn+uflwuUW9pb0VvdW9db2NvS297XAFOXAAdMtZKQC6azHg0PAAMjAAhiGMGAAqeAAi1orMgqKhZLlZxGQpF2vXtqnp4h+SgRkAqdPkokCIAFYwADGYCk-kMqQo6DgAGsYBAkAAzOCnNYAWkkrmQ6GweH2RxgJ1OKSwazw+ESQTea0IxBMKTRGOxuIClmiIFAbgAVHAkBJYjs4OTjmcXjiQcwwZCYXCdLI4AiaXBkZysTj8YTEKhMLgpYcZdTaay4OzddyPq4+aAhW4tqAoUg0KwWEghDAwAALVRkQz+TFIJCuUNq2QiA5sKP+dXqISuGqNJPq1gJuAAcmzuZwmZMRbVJf8jF9METMbgUDYSCgrj6pdk5bVYEbDMbrgK1VAJn5EviAGFfVABLR6ABVNAoT2nSVkaWUjBxGB6yt+wNcQj8txuODruBjoQTqez+doRfxMjmTtQbtQKx8czhpBuONsNzZl+Od+fvGbh3H+5hbjAbj1o25hbMeABCiQHCiZwKsoHBoJwlyodmu6kP4wLUDYSgGIY6CYqEABiXgXF4ZGhAA+r4qqyBRqEkXREiMUYNFGBxcCMboDg-BIzj4WxRhUdxtFoOREgAEpMf8KQUXgckOgC4j+K4KTnI45hrEO2zxAA8pO543jAZx4BQhE3GhXBYbZXw4RhyS5m4uYvBWKiuU5SgUP8wkBC53B+cwVyBREIn2b5ChfHa8qRYColqjZcVKE4-zAq4CGHMhpoXMQYWpHxKnajJoRqQ4rHFQlwLaLIplgOZOxnMpdJwAAojQbAHDCGByXgIWEJcxCuMJWkaWwsGSgAWskhhasip7njAM5zguOxrK4TUtbAa47JuVY7hh1mECYWzCse80hpmD5PuNGhRJmb4RoB36-q4IX8smr0fl+wHCOYj33GwP3qmBVaQQ2z4g5o-ImC6oBAA