typescript - 在 TypeScript 中将字符串映射到模板文字类型
问题描述
有没有办法将字符串映射到 TypeScript 中匹配的模板文字类型?
这是一个例子:
type SomeType<T> = {
[P in keyof T as `as${Capitalize<string & P>}`]: number;
};
这应该把每个属性x
都T
变成一个属性asX
。
但现在我想取一个属性名称foo
,并将其转换为asFoo
TypeScript 可以检测到的方式。
我希望能够做到这一点:
interface I {
foo: number;
bar: number;
}
const obj: SomeType<I> = {
asFoo: 1,
asBar: 2,
};
const str = 'foo';
// Doesn't work, trying to capitalize str, but TypeScript only sees it as a string
obj[`as${str[0].toUpperCase()}${str.slice(1)}`];
我想以某种方式获取str
和索引obj
. 这有可能吗?我想我可以投射字符串,但我宁愿不这样做。
目前我正在通过创建这样的函数来处理这个问题:
function getProperty(key: string): keyof SomeType<I> {
return key === 'foo' ? 'asFoo' : 'asBar';
}
obj[getProperty('foo')];
但我只是想看看是否有更优雅的解决方案,因为如果有很多属性,这可能会失控。我对 TypeScript 很陌生,所以我可能会遗漏一些东西。
解决方案
我通常会尝试将我的逻辑分成尽可能小的部分。考虑这个例子:
type SomeType<T> = {
[P in keyof T as `as${Capitalize<string & P>}`]: number;
};
interface Obj {
foo: number;
bar: number;
}
const obj: SomeType<Obj> = {
asFoo: 1,
asBar: 2,
};
const capitalize = <Key extends string>(key: Key) =>
`${key[0].toUpperCase()}${key.slice(1)}` as Capitalize<Key>
const withPrefix = <Key extends string>(key: Key): `as${Key}` => `as${key}`
const getProperty = <Key extends string>(key: Key) => withPrefix(capitalize(key))
const result = getProperty('foo') // asFoo
const getter = obj[result] // number
此行 as${Capitalize<string & P>}
包含两个操作:
大写,
添加
as
前缀
这就是为什么我使用了两个函数
您可能已经注意到,withPrefix
并且getProperty
可能由以下组成:
import { compose } from 'redux'
const capitalize = <Key extends string>(key: Key) =>
`${key[0].toUpperCase()}${key.slice(1)}` as Capitalize<Key>
const withPrefix = <Key extends string>(key: Key): `as${Key}` => `as${key}`
type Fn =
<Key extends string>(key: Key) => `as${Capitalize<Key>}`
const getProperty =
compose(withPrefix, capitalize) as Fn
const result = getProperty('foo') // asFoo
但它要求您使用compose
带有类型断言的额外函数。
您可以从文档中了解有关模板文字字符串的更多信息
推荐阅读
- javascript - MathGame 未捕获类型错误:无法将属性“onclick”设置为 null
- javascript - 如何为对象键设置初始值?
- django - 可空布尔字段的 Django 过滤器
- django - 无效的 HTTP_HOST 标头 - Django
- lua - _ENV 的 Lua 奇怪行为
- c - 使用指针从方法中获取 char 数组值。
- android - Firebase 函数 - ReferenceError:未定义事件
- r - 为什么 slotNames 在 data.frame 上工作,即使它不是真正的 S4 对象?
- python - 使用 Python 抓取 MediaWiki 网站(特定的 html 标签)
- html - 圆的边框样式为刻度