首页 > 解决方案 > Typescript 枚举作为参数类型允许无效值

问题描述

在 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

选择

如果我使用 atype而不是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'

标签: typescriptenums

解决方案


您可能对 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)

所以我想说的是,如果它是一个数字枚举,它只是化妆品,它被视为一个数字,但如果你制作一个字符串枚举,那么它实际上是在尝试匹配类型


推荐阅读