【发布时间】:2021-10-19 17:58:25
【问题描述】:
首先,我将提供一些背景信息:
我有两个接口,它们都继承了一个共同的基础。
interface Base { type: string }
interface Foo extends Base { type: "foo", name: string }
interface Bar extends Base { type: "bar", score: number }
我将两者都保存在联合类型中,因此我可以在存储两者之一的数组中使用它。
type Baz = Foo | Bar;
const storage : Baz[] = [];
我有一个存储联合类型所有可能的type 值的类型,以及一个只接受这些值的函数。
type BazTypes = Baz["type"]; // "foo" | "bar"
function readBaz(type : BazTypes) { /* ... */ }
现在,我正在尝试制作一个函数映射,它将解析Baz 提供的给定对象,给定它的类型,如下所示:
// Expectation:
{
"foo": (arg : Foo) => boolean, // (arg: {type: "foo", name: string}) => boolean
"bar": (arg : Bar) => boolean, // (arg: {type: "bar", score: number}) => boolean
}
type BazMap = {
[key in BazTypes]: (args : Baz extends {type: key} ? Baz : never) => boolean
};
const parsers : BazMap = {
"foo": (foo /* which should be of type Foo */) => { /* ... foo.name ... */ },
"bar": (bar /* which should be of type Bar */) => { /* ... bar.score ... */ },
}
但是,该映射反而提供联合类型本身,而不是给定类型的正确接口。
// Reality:
{
"foo": (arg : Foo | Bar) => boolean,
"bar": (arg : Foo | Bar) => boolean
}
type BazMap = {
[key in BazTypes]: (args : Baz extends {type: key} ? Baz : never) => boolean
};
const parsers : BazMap = {
"foo": (foo /* which is Foo | Bar */) => { /* Only foo.type can be accessed. */ },
"bar": (bar /* which is Foo | Bar */) => { /* Only bar.type can be accessed. */ },
}
因此,TypeScript 不提供name 和score,因为Foo 和Bar 中都不存在这两个值。
我正在尝试按预期获取地图。到目前为止,我还不能正确地创建一个接受正确类型的地图。
TL;DR:如何根据类型的参数创建 Object 类型?(例如,如果类型是 "foo",它将返回 Foo 的解析器(即不接受Bar)等)
【问题讨论】:
标签: typescript types