我有几个不同的接口和对象,每个都有type个属性.假设这些对象存储在NoSQL数据库中.如何根据输入参数type创建具有确定性返回类型的泛型getItem函数?

interface Circle {
    type: "circle";
    radius: number;
}

interface Square {
    type: "square";
    length: number;
}

const shapes: (Circle | Square)[] = [
    { type: "circle", radius: 1 },
    { type: "circle", radius: 2 },
    { type: "square", length: 10 }];

function getItems(type: "circle" | "square") {
    return shapes.filter(s => s.type == type);
    // Think of this as items coming from a database
    // I'd like the return type of this function to be
    // deterministic based on the `type` value provided as a parameter. 
}

const circles = getItems("circle");
for (const circle of circles) {
    console.log(circle.radius);
                       ^^^^^^
}

属性"radius"不存在于类型"Circle | Square"上.

推荐答案

Conditional Types人获救:

interface Circle {
    type: "circle";
    radius: number;
}

interface Square {
    type: "square";
    length: number;
}

type TypeName = "circle" | "square"; 

type ObjectType<T> = 
    T extends "circle" ? Circle :
    T extends "square" ? Square :
    never;

const shapes: (Circle | Square)[] = [
    { type: "circle", radius: 1 },
    { type: "circle", radius: 2 },
    { type: "square", length: 10 }];

function getItems<T extends TypeName>(type: T) : ObjectType<T>[]  {
    return shapes.filter(s => s.type == type) as ObjectType<T>[];
}

const circles = getItems("circle");
for (const circle of circles) {
    console.log(circle.radius);
}

谢谢西尔维奥为我指明了正确的方向.

Typescript相关问答推荐

如何在类型脚本中使用条件陈述循环

替换类型脚本类型中的多个特定字符串

TS 2339:属性切片不存在于类型DeliverableSignal产品[]上>'

有没有可能使用redux工具包的中间件同时监听状态的变化和操作

我用相同的Redux—Toolkit查询同时呈现两个不同的组件,但使用不同的参数

类型脚本泛型最初推断然后设置

如何使用泛型类型访问对象

如何在已知基类的任何子类上使用`extends`?

在保留类型的同时进行深层键名转换

跟踪深度路径时按条件提取嵌套类型

TypeScrip-根据一个参数值验证另一个参数值

Cypress-验证别名的存在或将别名中的文本与';if';语句中的字符串进行比较

为什么类型脚本使用接口来声明函数?他的目的是什么.

类型判断数组或对象的isEmpty

可以用任意类型实例化,该类型可能与

更漂亮的格式数组<;T>;到T[]

如何在Vue动态类的上下文中解释错误TS2345?

通过辅助函数获取嵌套属性时保留类型

如何在TypeScript中声明逆变函数成员?

如何确定剧作家中给定定位器的值?