索引到具有枚举索引的小元组会不正确地触发 TS2493
Indexing into a small tuple with an enum index improperly triggers TS2493
下面的代码是我正在尝试做的事情的要点
enum Foo {
Foo0, Foo1, Foo2, Foo3, Foo4 // many more
}
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
// Only Foo0 and Foo1 are valid to pass to bar
if(foo > 2) throw RangeError();
return baz[foo];
// ^ Linter gives the following, even though foo can't be greater than 2:
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '2'.
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '3'.
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '4'.
}
因为检查 foo
值的行,baz[foo]
永远不会大于 2。有什么办法可以让 Typescript 相信它不需要担心这个?
type predicate 可以帮忙
enum Foo {
Foo0, Foo1, Foo2, Foo3, Foo4 // many more
}
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
// Only Foo0 and Foo1 are valid to pass to bar
if(!checkIsFoo0OrFoo1(foo)) throw RangeError();
return baz[foo];
}
function checkIsFoo0OrFoo1(foo: Foo): foo is (Foo.Foo0 | Foo.Foo1) {
return foo > 2;
}
因为enum
键可以与任何值相关联,即它们不必是升序数字或从一个特定数字开始,而且编译器不提供具体值,所以似乎没有办法干净地处理这个。
我建议断言 foo 是一个数字并使用它(尽管这仍然有可能出错):
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
const index = foo as number;
if (index > 1) throw RangeError(); // if enum is 0-based (default)
return baz[index];
}
一般来说,您不应将 Enum
用于此类目的。
只需对 foo
参数使用 0|1
索引联合类型
type Foo = 0|1
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
return baz[foo];
}
下面的代码是我正在尝试做的事情的要点
enum Foo {
Foo0, Foo1, Foo2, Foo3, Foo4 // many more
}
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
// Only Foo0 and Foo1 are valid to pass to bar
if(foo > 2) throw RangeError();
return baz[foo];
// ^ Linter gives the following, even though foo can't be greater than 2:
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '2'.
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '3'.
// TS2493 [ERROR]: Tuple type '[any, any]' of length '2' has no element at index '4'.
}
因为检查 foo
值的行,baz[foo]
永远不会大于 2。有什么办法可以让 Typescript 相信它不需要担心这个?
type predicate 可以帮忙
enum Foo {
Foo0, Foo1, Foo2, Foo3, Foo4 // many more
}
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
// Only Foo0 and Foo1 are valid to pass to bar
if(!checkIsFoo0OrFoo1(foo)) throw RangeError();
return baz[foo];
}
function checkIsFoo0OrFoo1(foo: Foo): foo is (Foo.Foo0 | Foo.Foo1) {
return foo > 2;
}
因为enum
键可以与任何值相关联,即它们不必是升序数字或从一个特定数字开始,而且编译器不提供具体值,所以似乎没有办法干净地处理这个。
我建议断言 foo 是一个数字并使用它(尽管这仍然有可能出错):
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
const index = foo as number;
if (index > 1) throw RangeError(); // if enum is 0-based (default)
return baz[index];
}
一般来说,您不应将 Enum
用于此类目的。
只需对 foo
参数使用 0|1
索引联合类型
type Foo = 0|1
function bar(foo: Foo) {
const baz: [any, any] = [0,0];
return baz[foo];
}