Проблема еще больше. Нет возможности расширять Enums в TypeScript, для этого нет синтаксиса, и он не поддерживается, поэтому ваш код EnumVal extends MyEnum
будет работать только для MyEnum
. Если вы хотите расширить какой-либо вариант, создать буквальное объединение, например 'foo' | 'bar'
, тогда расширение имеет смысл.
Ниже приведено доказательство невозможности расширения Enum:
enum MyEnum {
FOO = 'foo',
BAR = 'bar'
}
enum MySubEnum {
FOO = 'foo',
}
type MySubEnumExtendsMyEnum = MySubEnum extends MyEnum ? true : false // false
exhaustiveSwitchGeneric(MySubEnum.FOO)
// compile error:
// Argument of type 'MySubEnum' is not assignable to parameter of type 'MyEnum'.
И последнее Плохая новость - эксклюзивный переход с дженериков невозможен. Но, к счастью, мы можем сделать некоторые обходные пути. Ниже приведен пример использования строковых литералов, как я уже сказал, нет возможности расширять Enum. Рассмотрим:
type MyVariant = 'foo' | 'bar';
type SubVariant = 'foo';
type SubVariantExtendsMyVariant = SubVariant extends MyVariant ? true : false; // true
function exhaustiveSwitchGeneric<Val extends MyVariant>(val: Val) {
const v = val as MyVariant // important line
switch (v) {
case 'foo':
break
case 'bar':
break
default:
const _a: never = v;
}
}
У нас есть трюк, работающий на val as MyVariant
, коммутатор эксклюзивный и должен иметь все варианты MyVariant