TypeScript:使用字符串字面量时的类型推断。

3
请看以下 TypeScript 代码。 很明显类型推断的行为就像注释中描述的那样。
现在问题是: 是否有可能以某种方式更改type V2 =...的定义,使其不再普遍推断为string,而是推断为类型"someOtherValue"
据我所知,根据TypeScript的类型推断规则,这是绝对不可能的...但谁知道呢? 为了保险起见,我最好向TypeScript社区寻求帮助。谢谢。
const config1 = { value: 'someValue' as const } 

type K1 = keyof typeof config1      // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)

const config2 = { value: 'someOtherValue' } 

type K2 = keyof typeof config2      // type K2: "value" (not string in general)
type V2 = (typeof config2)['value'] // type V2: string

TypeScript 游乐场:演示

2个回答

2

你需要在整个config2上使用const

const config2 = { value: 'someOtherValue' } as const;

否则它总是字符串。
使用关键访问。
const config1 = { value: 'someValue' as const } 

type K1 = keyof typeof config1      // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)

const config2 = { value: 'someOtherValue' } as const;

type K2 = keyof typeof config2 // type K2: "value" (not string in general)
type V2 = (typeof config2)[K2] // type V2: "someOtherValue"

@satanTime + @JózefPodlecki:将 as const 写在对象字面量后面而不是字符串本身后面,实际上是一个非常好的想法。在我的实际用例中 - 这比那个简单的例子要复杂一些;-) - 有一个函数,它以一个大的配置对象作为参数,我不想在某些特殊字符串后面写上几十次 as const...但如果我只在大的配置对象后面写上 as const,类型推断就会按预期工作。非常感谢你们,你们真的帮了我很大的忙 :-) - Natasha

1
现在的问题是:有没有可能以某种方式更改类型V2 = ...的定义,使它不再推断为一般的字符串,而是推断为类型"someOtherValue"?是的,你需要使用const断言告诉typescript该类型不会改变。你可以将其应用于value属性或整个对象,就像@satanTime建议的那样。
为什么?因为typescript认为你可能会做以下事情。
const config2 = { value: 'someOtherValue' } 
config2.value = "something different"

应用const断言后,类型检查器可以决定进行类型缩小。
const config1 = { value: 'someValue' as const } 
config1.value = "test" // Type '"test"' is not assignable to type '"someValue"'.
const config2 = { value: 'someOtherValue' } as const
config2.value = "test" // Cannot assign to 'value' because it is a read-only property.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接