在TypeScript中,我定义了一个enum
,然后我想要一个函数采用一个参数,该参数的值是枚举的值之一。但是,TypeScript似乎不对值进行任何验证,并且允许在枚举之外的值。有办法吗?
enum myenum {
hello = 1,
world = 2,
}
const myfunc = (num:myenum):void => console.log(`num=${num}`);
myfunc(1); // num=1 (expected)
myfunc(myenum.hello); // num=1 (expected)
//THE ISSUE: I'm expecting next line to be a TS compile error, but it is not
myfunc(7); // num=7
如果我使用type
而不是enum
,我可以得到与所需内容类似的内容,但会丢失枚举的某些功能。
type mytype = 1|2;
const myfunc = (num:mytype):void => console.log(`num=${num}`);
myfunc(1);
myfunc(7); //TS Compile Error: Argument of type '7' is not assignable to a parameter of type 'mytype'
到目前为止,似乎是working as designed。
答案 0 :(得分:1)
您可能对TS中的枚举有太多期望...:)
enum MyCoolEnum {
A = 1,
B = 2,
}
function test(data: MyCoolEnum) {
console.log(`Test = ${typeof data}`)
}
test(1)
test(MyCoolEnum.A)
test(500)
如果在上面运行此代码,您将看到所有行都打印number
,这意味着在幕后将其转换为数字,这就是为什么它接受所有内容的原因……枚举通常只是一个不错的选择练习避免使用幻数,并使代码更具可读性
另一方面,如果您停止使用数字枚举并将A和B的值实际上更改为字符串,则会得到:
TSError: ⨯ Unable to compile TypeScript:
dima.ts:10:6 - error TS2345: Argument of type '1' is not assignable to parameter of type 'MyCoolEnum'.
10 test(1)
~
dima.ts:12:6 - error TS2345: Argument of type '500' is not assignable to parameter of type 'MyCoolEnum'.
12 test(500)
~~~
at createTSError (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:423:12)
at reportTSError (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:427:19)
at getOutput (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:554:36)
at Object.compile (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:760:32)
at Module.m._compile (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:839:43)
at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/odinn/.nvm/versions/node/v10.15.1/lib/node_modules/ts-node/src/index.ts:842:12)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
所以我想说的是,如果它是一个数字枚举,则只是化妆品,并且将其视为数字,但是例如,如果您创建一个字符串枚举,则实际上是在尝试匹配类型