Typescript 类型脚本类型是否依赖于属性名称?
这是一个有点奇怪的问题,但我仍然对它的可能性感到好奇 我有一个来自API的JSON结构,它定义了如下映射:Typescript 类型脚本类型是否依赖于属性名称?,typescript,Typescript,这是一个有点奇怪的问题,但我仍然对它的可能性感到好奇 我有一个来自API的JSON结构,它定义了如下映射: "sizes: { "thumbnail": "xxxx", "thumbnail-width: 150, "thumbnail-height: 150, "medium: "xxx", "medium-width": 500,
"sizes: {
"thumbnail": "xxxx",
"thumbnail-width: 150,
"thumbnail-height: 150,
"medium: "xxx",
"medium-width": 500,
"medium-height": 500,
...
}
名称在某种程度上是预定义的,但实际上不是
我的问题是,是否可以将任何以-width或-height结尾的属性定义为number,而将其他所有属性定义为string。类似正则表达式(.*)-(宽度|高度):数字
TypeScript可以做各种神奇的事情,但它能做这样的事情吗?从TypeScript 4.1开始,可以使用文字类型。 例如:
type AddSuffixToEachProps<T, Suffix extends string, Value extends any> = T & {
[P in keyof T as `${string & P}-${Suffix}`]: Value
}
输入AddSuffixToEachProps=T&{
[P在T的键中作为`${string&P}-${Suffix}`]:值
}
这是一种接受某种模式的类型,并为每个道具添加后缀
用法:
type Result = AddSuffixToEachProps<{
foo: string,
bar: string[]
}, 'width', number>
const test: Result = {
foo: 'some string',
"foo-width": 123, // required
bar: ['one', 'two', 'three'],
"bar-width": 456 // required
}
type Result=addSuffExtoeAchProps
常数测试:结果={
foo:'一些字符串',
“foo宽度”:123,//必需
吧台:['1','2','3'],
“钢筋宽度”:456//必填项
}
不,不可能
因为
索引签名参数类型必须为“字符串”或“数字”
我们现在不能将type
${string}-width
或${string}-height
设置为大小的键类型,从TS4.1开始,TypeScript中没有具体的类型(我们称之为值
)来表示可分配给值
属性的值。作为记录,我将其解释为:任何字符串键都是可以接受的;如果键以-width
或-height
结尾,则属性必须是数字
;否则它必须是字符串
。没有要求这些密钥必须显示为三元组;例如,如果“键”
是键,则不要求存在“键高”
或“键宽”
也许当被寻址时(如果被合并的话),您将能够使用`${string}-width`
格式的“模式”模板文本(如中实现的)作为键。现在你不能
目前,对于适当的K
,您只能将您的限制表示为值的形式:
type Values<K extends string> = {
[P in K]: P extends `${string}-${"height" | "width"}` ? number : string
};
让我们试试看:
const sizes = asValues({
"thumbnail": "xxxx",
"thumbnail-width": 150,
"thumbnail-height": 150,
"medium": "xxx",
"medium-width": 500,
"medium-height": 500,
}); // okay
const badSizes = asValues({
"toenail": 123, // error! Type 'number' is not assignable to type 'string'
"toenail-width": 456,
"psychic": "yyy",
"psychic-height": "tall" // Type 'string' is not assignable to type 'number'
})
看起来不错<接受代码>大小
,但不良大小
会导致类型不正确的属性出错
当然,我们使用泛型的事实意味着您必须将泛型类型参数K
拖到您想要强制执行此限制的任何地方。如果将其用于整个代码库,可能会变得笨拙。相反,您可能只想使用值
来验证传入的对象文本,然后在操作它们时,将其扩展到TypeScript可以表示的最接近的特定类型,如属性为string | number
的类型:
type WideValues = { [k: string]: string | number };
const wideValues: WideValues = sizes; // okay
因此,您使用值
进行验证,然后使用宽值
进行操作
如果前缀是预先知道的,但问题表明它们不是(或者在任何情况下“不是真的”)。这种想法Record`会起作用,但不会。非常酷,但只有在编译时知道键时才起作用,在这种情况下,我还可以定义width和height属性。不要认为这可以解释为typet={[x in`${string}-width` |${string}-height`]:number}
编译得很好,但不知何故解析为t={}
,这对我来说似乎有问题。是的,对我来说也有问题。我认为这个功能还没有完全被支持。是的,这是目前已知的问题
type WideValues = { [k: string]: string | number };
const wideValues: WideValues = sizes; // okay