typescript - 从字符串动态创建字符串文字类型
问题描述
有没有办法从字符串动态创建字符串文字类型,而不是从字符串中创建一个数组,然后使用 typeof 提取其类型,如this answer所示?
const url = 'text'
const URL = [url]
type P = (typeof URL)[number];
编辑我想要实现的是构建,一种基于给定字符串(端点 URL)的方法将能够提取我需要提供的端点参数所需的内容。
export type ExtractRouteParams<T> = string extends T
? Record<string, string>
: T extends `${infer _Start}:${infer Param}/${infer Rest}`
? { [k in Param | keyof ExtractRouteParams<Rest>]: string }
: T extends `${infer _Start}:${infer Param}`
? { [k in Param]: string }
: {};
ExtractRouteParams 是一种基于给定字符串返回我的类型的类型,该类型定义了需要什么样的参数。当我这样使用它时,它工作得很好。
type Test = ExtractRouteParams<'actions/:actionId/test/:testId'>
但我希望它更动态地工作。我创建了一个工厂 URL 方法,我想在其中基于作为参数提供的 URL 创建类型。该方法返回泛型类(基于该动态类型),其中包含创建 url 的方法。
export function urlFactory(url: string) {
type P = typeof url;
return new InterpolateUrl<P>();
}
class InterpolateUrl<T extends string> {
url(params: ExtractRouteParams<T>): void {
}
}
const endpoints = {
endpoint: urlFactory(
'actions/:actionId/test/:testId'
)
};
不幸的是 InterpolateUrl 类方法url没有正确指向所需的params。相比之下,类型 Test 确实如此。
这里游乐场
解决方案
更新
鉴于您更新的问题和示例,看起来您想要的只是让您的urlFactory()
函数本身是generic。编译器并不会真正查看特定类型string
并对其进行通用处理,因为输出类型对您来说会更好;当你需要泛型时,你必须告诉编译器:
export function urlFactory<P extends string>(url: P) {
return new InterpolateUrl<P>();
}
一旦你这样做,事情就会如愿以偿,我认为:
console.log(endpoints.endpoint.url({
actionId: "hey",
testId: "you"
})); // okay
console.log(endpoints.endpoint.url({
// error!
// Type '{}' is missing the following properties from type
// '{ actionId: string; testId: string; }': actionId, testId
}))
原始答案
您可以直接使用TypeScripttypeof
类型查询运算符url
,而无需创建中间数组:
const url = 'text'
type P = typeof url;
// type P = "text"
推荐阅读
- excel - 问:COUNTIF 仅当 COUNTIF
- c# - 如何检查文件夹是否为空?
- java - 如何使用 System.out.print 使方法成为原子方法
- material-ui - 在 MUI v5 中,如何使所有元素高度相同并垂直对齐?
- google-cloud-platform - 在 GCP vms 中将磁盘挂载到 /home 或 /usr
- typescript - 使用全局类型或回退到本地类型
- java - 如何将本地项目实施到具有此特定目录结构且不将其转换为二进制文件的其他本地项目
- python - 尝试在 Tensorflow 中组合数字和文本特征:ValueError:层模型需要 2 个输入,但它接收到 1 个输入张量
- python - 如何打印列表中的浮点数
- html - 输入文本框以显示结束部分而不是从开始