ale*_*ird 4 typescript typescript2.0
我想要一个类型来描述一组字符串,以及一个带有键的对象,以便于访问所述字符串.
当const TwoWords与所有键的值初始化类型断言TwoWords,然后DoSomething(TwoWords.Foo)编译,但预期在switch语句中的typeguard不起作用-类型word在默认情况下是不是never.
type TwoWords = 'foo' | 'bar';
const TwoWords = {
Foo: 'foo' as TwoWords,
Bar: 'bar' as TwoWords
};
function DoSomething(word: TwoWords) {
switch (word) {
case TwoWords.Foo:
break;
case TwoWords.Bar:
break;
default:
let typeInferenceCheck: never = word; // Type '"foo"' is not assignable to type 'never'
}
}
DoSomething(TwoWords.Foo);
DoSomething('bar');
Run Code Online (Sandbox Code Playgroud)
但是,如果我为每个TwoWords键的值使用字符串文字类型断言word,则默认情况下的类型never与我期望的类型相同.
type TwoWords = 'foo' | 'bar';
const TwoWords = {
Foo: 'foo' as 'foo',
Bar: 'bar' as 'bar'
};
function DoSomething(word: TwoWords) {
switch (word) {
case TwoWords.Foo:
break;
case TwoWords.Bar:
break;
default:
let typeInferenceCheck: never = word; // OK
}
}
DoSomething(TwoWords.Foo);
DoSomething('bar');
Run Code Online (Sandbox Code Playgroud)
在案件'foo'和'bar'长得多串(比方说,一个完整的句子),我不想重复他们-它太冗长.是否有另一种方法可以使用字符串键控枚举,从switch语句(或if/else链)中的类型推断透视图中按预期运行?
根据Madara Uchiha的回答,您可以使用TypeScript 2.4字符串枚举获得正确的类型推断(如选项2中所示),但这些不可与字符串文字互换.
DoSomething('bar'); // Type '"bar"' is not assignable to parameter of type 'TwoWords'
Run Code Online (Sandbox Code Playgroud)
(有关StringScript 2.4字符串枚举的字符串文字赋值,请参阅GitHub问题#15930)
我正在寻找另一个允许我拥有的选项:
EnumLikeObject.Foo === 'foo'let thing: EnumLikeObject = 'foo'let thing: EnumLikeObject = EnumLikeObject.Foo异议和讨论
如果你想等待和忍受一点,
TypeScript 2.4为游戏领域带来了真正的字符串枚举:
enum TwoWords {
Foo = 'foo',
Bar = 'bar'
}
function DoSomething(word: TwoWords) {
switch (word) {
case TwoWords.Foo:
break;
case TwoWords.Bar:
break;
default:
let typeCheck: never = word; // OK
}
}
Run Code Online (Sandbox Code Playgroud)
这可以让你获得两全其美.
我想我明白了。至少:
DoSomething接受"foo"或"bar"。并满足您的标准
TwoWords.Foo === 'foo'言归正传:
const TwoWords = (function () {
const Foo = 'foo';
const Bar = 'bar';
const ret = {
Foo: Foo as typeof Foo,
Bar: Bar as typeof Bar,
};
return ret;
})()
type TwoWords = typeof TwoWords[keyof typeof TwoWords];
Run Code Online (Sandbox Code Playgroud)
然后我突然灵光一现
namespace TwoWords2 {
export const Foo = "foo";
export const Bar = "bar";
}
type TwoWords2 = typeof TwoWords2[keyof typeof TwoWords2]
// didn't test this, not sure if it actually updates the
// original object or just returns a frozen copy
Object.freeze(TwoWords2);
Run Code Online (Sandbox Code Playgroud)
在我看来,这不是一个缺点,因为它仍然会在类型检查器和 VS Code 中引发错误,但TwoWords2.Bar = "five"实际上是有效的,因为命名空间被编译为一个简单的对象。但这就是打字稿的工作方式。显然,第一个代码也有这个问题,但它不会抛出类型错误,所以第二个代码更好,IMO。
| 归档时间: |
|
| 查看次数: |
939 次 |
| 最近记录: |