映射类型不符合类型限制 `类型 "" 不能分配给类型 'never'`

问题描述 投票:0回答:1

我最近玩过打字稿泛型,发现了我不知道如何解释的行为,在我的恳求下:

具有初始值的枚举列表
几个显示结果的类,一个类恰好对应一个枚举值

所以任务是编写将初始值映射到结果值的函数(简单的 switch 情况),但这对我来说还不够,因为这种情况的类型类似于:

1 个枚举 => 任何结果类

所以我继续使用泛型,创建初始枚举到结果值的类型映射,制作泛型函数,在这种情况下工作正常,类型现在很好:

1 个枚举 => 1 个结果类

但问题是,在这种情况下,打字稿不想识别返回值的类型,因此我将类型转换为任何类型,有一个最小的playground和链接过期时的代码:

enum TestKind {
    String = 'str',
    Number = 'num',
    Boolean = 'bool',
}

type TestKindTypeMap = {
    [TestKind.String]: string;
    [TestKind.Number]: number;
    [TestKind.Boolean]: boolean;
};

function transformerWithBadTyping(input: TestKind): TestKindTypeMap[TestKind] {
    switch (input) {
        case TestKind.String:
            return '';
        case TestKind.Number:
            return 0;
        case TestKind.Boolean:
            return false;
        default:
            throw new Error();
    }
}

console.log(transformerWithBadTyping(TestKind.String))
console.log(transformerWithBadTyping(TestKind.Number))
console.log(transformerWithBadTyping(TestKind.Boolean))

function transformer<K extends TestKind>(input: K): TestKindTypeMap[K] {
    switch (input) {
        case TestKind.String:
            return '';
        case TestKind.Number:
            return 0 as any;
        case TestKind.Boolean:
            return false as TestKindTypeMap[K];
        default:
            throw new Error();
    }
}

console.log(transformer(TestKind.String))
console.log(transformer(TestKind.Number))
console.log(transformer(TestKind.Boolean))

所以问题是:

  1. 我的代码/ts 有什么问题以及为什么在这种泛型函数的情况下我要将类型转换为 TestKindTypeMap[K]any?为什么打字稿没有我的帮助就无法继续?
  2. 还有其他方法可以实现严格打字吗?
typescript generics enums
1个回答
0
投票

Typescript 无法缩小来自泛型参数的类型,解决方法如下:

游乐场

function transformer<K extends TestKind>(input: K): TestKindTypeMap[K] {

    const out : {[K in TestKind]: (input: K) => TestKindTypeMap[K]} = {
        [TestKind.String]: () => '',
        [TestKind.Number]: () => 0,
        [TestKind.Boolean]: () => false
    };

    return out[input](input);

}
© www.soinside.com 2019 - 2024. All rights reserved.