我有一个函数,只能接受两个可能的值(用于验证)。为此,我这样做:
interface PossibleValues {
key: "str1" | "str2";
}
我只能使用 string 类型调用该函数。这是我们的建筑设计,我必须处理。
set({key: type})
因为type
是 string ,而key
只能接受"str1" | "str2"
,它表示:
TS2322:类型'string'不能分配给类型'“ str1” | “ str2”” 。
问题是如何以最优雅的方式克服这一问题?我的意思是我想传递一个 string ,但是如果该字符串不是两个"str1" | "str2"
我试图做的是:
set({key: type} as PossibleValues)
并停止抱怨,但未实现所需的行为。例如,如果我通过“ str333”,它仍然可以工作。
有什么想法吗?
答案 0 :(得分:3)
您需要认识到TypeScript只是在帮助您解决编译时错误。它对运行时不起作用,因为它已编译为JavaScript。类型和接口不存在。
话虽这么说,除非您是硬编码字符串以传递给此函数str1 | str2
,否则您不应该依赖TypeScript类型来确保其正常工作。
您需要编写JavaScript检查代码,并允许将任何字符串传递给函数。
您可以创建一个类型保护来实现此效果。
function isKey(value: string): value is "str1" | "str2" {
return value === "str1" || value === "str2";
}
然后,您可以使用它告诉TypeScript您已检查类型。
if(isKey(type)) {
set({ key: type }); // typescript won't complain anymore because you did a type check
}
答案 1 :(得分:0)
您需要使用特定的联合类型键入您命名为type
的变量。
type PossibleValue = 'str1' | 'str2'
interface MyInterface {
key: PossibleValue
// ...
}
const set = (data: MyInterface) => { /* ... */ }
let type: PossibleValue = 'str1' // OK
type = 'str2' // OK
type = 'str3' // Type '"str3"' is not assignable to type 'PossibleValue'.
set({ key: type }) // OK
set({ key: 'str3' }) // Type '"str3"' is not assignable to type 'PossibleValue'.
答案 2 :(得分:0)
添加到Todd Skelton出色的answer中,如果您使用的是Typescript 3.4+,则可以使用以下语法定义类型保护:
const keys = ['str1', 'str2'] as const
type Key = typeof keys[number]
const isKey = (s: string): s is Key => keys.some((k) => k === s)
这种方法的好处是,如果您要添加/删除可能的值,则只需修改keys
数组。