我有一个API,它以类似的形式返回一个对象:
{
foo: number,
foo_comment: string,
foo_formatted_value: string,
_foo_created_by: string
bar: number,
bar_comment: string,
bar_formatted_value: string,
_bar_created_by: string
}看看这个答案,看起来我可以创建一个泛型,在对象的键中添加一个前缀。是否有一种方法可以使泛型以相同的方式接受模板文字参数?
我在想这样的事情:
type Data = {
foo: number,
bar: number
}
type Template<T, TemplateFunction extends TemplateLiteralFunction, V = void> = {
[K in keyof T as K extends string ? TemplateFunction(K) : never]: (V extends void? T[K]: V)
}
type DataAndMetaData =
Data &
Template<Data,`${1}_comment`>&
Template<Data,`${1}_formatted_value`>&
Template<Data,`_${1}_created_by`>;当然,${1}是不起作用的部分。也许如果有类型生成函数:(Key:string)=>'${Key}...'
发布于 2022-09-20 18:37:40
您不能以这种方式抽象模板文字类型,但您不需要这样做。相反,您可以使用普通字符串文字类型并使用模板文字类型推断来用所需的键替换您的"${1}"字符串。
看起来可能是这样的:
type Template<T, S extends string, V = void, I extends string = "${1}"> = {
[K in keyof T as K extends string ?
S extends `${infer F}${I}${infer R}` ? `${F}${K}${R}` : K :
K]: V extends void ? T[K] : V;
}我们可以这样使用它:
type DataAndMetaData =
Data &
Template<Data, "${1}_comment" | "${1}_formatted_value" | "_${1}_created_by", string>
/* type DataAndMetaData = Data & {
foo_comment: string;
foo_formatted_value: string;
_foo_created_by: string;
bar_comment: string;
bar_formatted_value: string;
_bar_created_by: string;
}*/请注意,您可以编写Data & Template<Data, "${1}_comment", string> & Template<Data, "${1}_formatted_value", string> & Template<Data, "_${1}_created_by", string>,但是使用分布型行为一次获得所需的输出类型会更清晰(或者几乎是如此.仍然需要初始的Data & )。
另外,在上面,"${1}"值本质上是任意的,因为我们实际上并没有使用模板文字插值。也许你想用不同的符号来表示要替换的东西。我添加了另一个类型参数I来表示这个值,并使其成为默认设置到"${1}"。因此,您可能希望更改默认值,甚至在使用Template时显式设置它。
type Also = Template<Data, "*" | "*_xyz", string, "*">
/* type Also = {
foo: string;
foo_xyz: string;
bar: string;
bar_xyz: string;
} */还请注意,上面的定义只执行一个替换,如果包含sigil的多个实例,则会表现得很奇怪:
type Hmm = Template<Data, "${1}_or_not_${1}_that_is_the_question">;
/* type Hmm = {
"foo_or_not_${1}_that_is_the_question": number;
"bar_or_not_${1}_that_is_the_question": number;
} */我假设这并不重要,但如果是这样的话,我们可以编写一个递归版本的替换逻辑来处理它--在另一个问题中,因为它超出了这个问题的范围。
https://stackoverflow.com/questions/73790777
复制相似问题