Typescript-如何使用运行时类型信息处理通用数据类型

时间:2019-11-04 02:44:06

标签: typescript

我有一个通用的容器类型,可能包含不同类型的数据。包含的数据类型在运行时受到包含字符串的“类型”字段的约束:

type Type = "Numeric" | "Text";

type DataTypeFor<T extends Type> =
    T extends "Numeric" ? number
    : T extends "Text" ? string
    : never;

interface Container<T extends Type> {
    type: T;
    data: DataTypeFor<T>;
}

但是,当我们要在此接口的实例上进行操作时,编译器无法推断data字段的正确类型:

function operate<T extends Type>(container: Container<T>) {
    switch (container.type) {
        case "Numeric":
            // Error
            const a: number = container.data;
            console.log(a);
            break;
        case "Text":
            // Error
            const b: string = container.data;
            console.log(b);
            break;
        case "Fsasefsef":
            // No error here! Why?
            break;
    }
}

对于此类实例中类型推断如何与泛型一起工作,我必须有一个稍微错误的认识。

有什么方法可以实现我想要的模式吗?

Typescript playground

1 个答案:

答案 0 :(得分:1)

您可以通过使用区分联盟来实现此模式。 https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions

示例:

interface Numeric {
    type: "Numeric"
    data: number
}

interface Text {
    type: "Text"
    data: string
}

type Container = Numeric | Text

function operate(container: Container) {
    switch (container.type) {
        case "Numeric":
            const a: number = container.data;
            console.log(a);
            break;
        case "Text":
            const b: string = container.data;
            console.log(b);
            break;
    }
}

http://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgHIFcC21gOQbwChkTkwBPABwgC5kAiDbKXe40gEzjDjpCwBG0QgF9ChUJFiIUAFQgAPMAXYkK1OvXlK2pZFx50AzmBYgA5qPHqUAYQD24OKGjIAvGiw48AH2TawcRh0EAQwYEdke2oobggACgRHHhcoOgcnVIBKFT0jAHdgMAQAC2RE5OcQaAA6GxyiPT0EOCMURi8WBHoaVSbmxxNkXmR+TCEod2QkzOqoGoM4AG4+-pIZo3sAGwgarftzeLgslbWmgSgIOABrU7WWtoYAntX7weUBY1NQcymZlLmC24y1e-Q2212+0OAhOoPOlxudxIYhEQA