这个想法告诉TypeScript:“让此let的值成为这些对象的任何值”
假设的例子:
const Types = {
ADD: 'ADD',
REMOVE: 'REMOVE'
}
let type: Object.values(Types) = 'ADD'
当我在TypeScript下方键入代码时,会向我显示可接受的值:“ ADD”或“ REMOVE”。
type = '|'
我可以手动let type: 'ADD' | 'REMOVE' = 'ADD'
进行此操作,但是我希望它是自动的。
有人知道该怎么做吗?或者您可以帮我吗?
答案 0 :(得分:2)
您可以通过以下类型别名表示“对象的值类型”:
type ValueOf<T> = T[keyof T];
然后将您的type
变量注释为ValueOf<typeof Types>
,如下所示:
let type: ValueOf<typeof Types> = "ADD"; // inferred as string
typeof Types
是必需的,因为Types
是运行时存在的值,而不是 type 。要获取与值对应的类型,可以使用typeof
type query operator。
请注意,尽管皱着眉头,但是...我们面临的问题是编译器已将Types
对象解释为具有string
属性,而您希望它将这些属性视为{{3 }}。 TypeScipt 3.4具有string literal types,可简化此操作:
const Types = {
ADD: 'ADD',
REMOVE: 'REMOVE'
} as const; // TS3.4+
// inferred as type { readonly ADD: "ADD"; readonly REMOVE: "REMOVE"; }
如果您还没有使用TypeScript 3.4,仍然可以使用如下帮助程序功能来获得此行为:
// interpret string literal values as string literal types:
const lit = <T extends string>(x: T) => x;
const Types = {
ADD: lit('ADD'),
REMOVE: lit('REMOVE')
};
// inferred as type { ADD: "ADD"; REMOVE: "REMOVE"; }
无论哪种情况,现在都将按您的预期推断类型:
let type: ValueOf<typeof Types> = "ADD"; // inferred as "ADD" | "REMOVE"
现在看起来不错。希望能有所帮助;祝你好运!
答案 1 :(得分:1)
在键/值相同的情况下,解决方案很简单:
const Types = {
ADD: 'ADD',
REMOVE: 'REMOVE'
}
let x: keyof typeof Types = 'ADD'
但是,正如您所指出的,实际示例中的值是不同的。
您将需要引入一个联合类型,最好是在创建对象之前。原因是,将其添加到对象之后而不在原始对象的类型信息上使用它会在类型检查中留下可能的空白(这将使我可以Types
内正确地更改值)。
我给值赋予了不同的名称,因为使用相同的键/值表明了先前的解决方法。
type AddRemove = 'ADDV' | 'REMOVEV';
const Types: { [key: string]: AddRemove } = {
ADD: 'ADDV',
REMOVE: 'REMOVEV'
}
let x: AddRemove = 'ADDV'
您可能能够以其他方式解决问题,例如使用enum
或使用受歧视的联合,这取决于您将其用于什么目的。