首页 > 解决方案 > 确保接口与联合类型相同?

问题描述

鉴于这种联合类型:

type Type = 'one' | 'two' | 'three'

如何键入以下对象以确保它 a) 涵盖Type;的所有可能值 b) 允许我拥有每种类型的函数签名?

const factories = {
    one(a: string) { return /* whatever */ },
    two(a: number, b: number) { return /* whatever */ },
    three() { return /* whatever */ }
}

function getFactory<T extends keyof typeof factories>(type: T): typeof factories[T] {
    return factories[type]
}

如果我不键入对象,就像上面那样,我有完整的类型检查但不是详尽的 - 我很容易忘记或拼错成员。在我的实际用例中,Type有 30 多种可能性并且还在不断增长,所以这真的很重要。

如果我使用 a Record,例如const factories: Record<Type, any>or const factories: Record<Type, Function>,它会详尽无遗,但我会放松对函数签名的类型检查。

标签: typescript

解决方案


如果您只是希望打字稿在缺少键时抛出错误,那么只需在声明后添加一个强制转换:

const factories = {
    one(a: string) { return /* whatever */ },
    two(a: number, b: number) { return /* whatever */ },
    three() { return /* whatever */ }
};

factories as Record<Type, any>;

如果您更改threefoo,则转换将出错,指出存在不兼容的错误类型。您也可以使用强制打字稿将键类型缩小到的函数Type

type Type = 'one' | 'two' | 'three';

function forceTypeKey<T>(obj: Record<Type, any> & T): T {
    return obj;
}

const factories = forceTypeKey({
    one(a: string) { return /* whatever */ },
    two(a: number, b: number) { return /* whatever */ },
    three() { return /* whatever */ }
});

推荐阅读