从不按预期工作的数组派生类型(斯塔克布利茨来说明这一切)。
为了改进代码库的某些部分,我无意中发现了几个用于将信息从后端映射到人类可读字符串的不同数组--如下所示:
export const MyMapping = [
{ dbLabel: 'something', screenLabel: 'Something User-friendly' },
...
];由于这种情况存在于几个地方,但是数组的“契约”并没有被某种类型强制执行,所以我接着写了以下内容:
export type DbLabelMapper = Record<'dbLabel' | 'screenLabel', string>;(实际上,第一个版本使用了一个接口,但想法是一样的)
然后,由于数据库标签在代码基的其他部分中被用作类型,但被错误地用作strings,我接着如下:
export const MyMapping: Array<DbLabelMapper> = [
{ dbLabel: 'something', screenLabel: 'Something User-friendly' },
...
] as const;
export type MyMappingType = typeof MyMapping[number]['dbLabel'];打字稿对我大喊大叫,因为我不应该把只读类型([...] as const)分配给可变类型(Array<DbLabelMapper>)。因此,我将映射签名更正如下:
export const MyMapping: Readonly<Array<DbLabelMapper>> = [
{ dbLabel: 'something', screenLabel: 'Something User-friendly' },
...
] as const;
export type MyMappingType = typeof MyMapping[number]['dbLabel'];现在,在那之后,我的MyMappingType没有任何类型。根据我的例子,我想要的是MyMappingType = 'something' | 'anotherThing' | '...'。我是不是做错了什么,还是错过了什么?
发布于 2022-11-24 17:08:45
您给了MyMapping一个显式的Readonly<Array<DbLabelMapper>>类型。使用typeof MyMapping将返回此类型。
要解决这个问题,您必须删除类型注释,并让TypeScript推断类型。
export const MyMapping = [
{ dbLabel: 'something', screenLabel: 'Something User-friendly' },
] as const但是您将失去以前的类型安全性,因为您现在可以将任何值分配给MyMapping。
TypeScript 4.9将引入satisfies操作符来帮助解决这种情况。
export const MyMapping = [
{ dbLabel: 'something', screenLabel: 'Something User-friendly' },
] as const satisfies Readonly<Array<DbLabelMapper>>
export type MyMappingType = typeof MyMapping[number]['dbLabel'];
// ^? type MyMappingType = "something"https://stackoverflow.com/questions/74564011
复制相似问题