如何解决TypeScript 从常量模板文字推断模板层数 TypeScript 4.3 更新:TS 4.2 的上一个答案:
我尝试使用精美的 TypeScript 模板文字来键入 REST API。我有一个适用于 const
字符串类型和 const
Javascript 模板文字类型的系统,但不适用于具有未知值的 Javascript 模板文字。
考虑以下递归路径解析器。
type PathVariable = string;
type ExtractPathVariable<T extends string> = T extends `:${string}`
? PathVariable
: T;
type PathParts<Path extends string> = Path extends `/${infer Rest}`
? PathParts<Rest>
: Path extends `${infer Start}/${infer Rest}`
? [ExtractPathVariable<Start>,...PathParts<`${Rest}`>]
: Path extends `${infer Item}`
? [ExtractPathVariable<Item>]
: never;
它给出了某些情况下的预期结果
// A == ["short","url","path"]
type A = PathParts<"/short/url/path">;
const b = `/short/url/path` as const;
// B == ["short","path"]
type B = PathParts<typeof b>;
// C == ["short","${y}","path"]
type C = PathParts<"/short/${y}/path">;
const d = `/short/${45}/path` as const;
// D == ["short","45","path"]
type D = PathParts<typeof d>;
但是,我最感兴趣的情况(因为我就是这样调用 API 的),它不起作用。
let y: unknown;
const e = `/short/${y}/path`;
// E == never
type E = PathParts<typeof e>;
有没有办法让 PathParts<typeof e>
工作? E == ["short",string,"path"]
或 E == ["short",unknown,"path"]
的结果会很好。
解决方法
TypeScript 4.3 更新:
问题 microsoft/Typescript#43060 已被拉取请求 microsoft/Typescript#43361 标记为已修复,该请求应与 TypeScript 4.3 一起发布。那时,您上面的代码将起作用(只要您使用我在下面提到的 const
assertion):
let y: unknown;
const e = `/short/${y}/path` as const;
// const e: `/short/${string}/path`
type E = PathParts<typeof e>;
// type E = ["short",string,"path"]
您可以在这里看到它的实际效果:Playground link to code
TS 4.2 的上一个答案:
抱歉,我认为从 TypeScript 4.2 开始,这是不可能的。
首先,为了接近这种行为,您需要使用 const
assertion 来告诉编译器您希望将 e
推断为模板文字类型,而不仅仅是 { {1}}。虽然有一个一致性参数,如 string
被推断为 const foo = "abc"
,所以 "abc"
应该被推断为类型 const bar = `abc${x}`
等,如 {{3} 中的要求},这个变化最终变成了 microsoft/TypeScript#41631。所以你需要 `abc${string}`
:
as const
但这就是我们所能做到的。您正在尝试将具有多个 const e = `/short/${y}/path` as const
// const e: `/short/${string}/path`
位置的模板文字类型与具有“模式”文字如 infer
的另一个模板文字类型相匹配(其中模式文字在 breaking too much real world code 中实现。但根据对于 microsoft/TypeScript#40598 这是不可能的(它提到了 `${number}`
而不是 `${number}`
,但所有模式文字都会出现相同的情况):
`${string}
该问题尚未归类为错误/限制/建议,但它与被视为建议的 microsoft/TypeScript#43060 相关。目前似乎没有一种机制可以让这种推理发挥作用。我也找不到任何行为合理的解决方法。
如果您想看到这种情况发生,您可能想要去解决这些问题中的任何一个并给 ? 和/或描述为什么您的用例令人信服。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。