I have a few different interfaces and objects that each have a type
property. Let's say these are objects stored in a NoSQL db. How can I create a generic getItem
function with a deterministic return type based on its input parameter type
?
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);
^^^^^^
}
Property 'radius' does not exist on type 'Circle | Square'.
Conditional Types
to the rescue:
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);
}
Thanks Silvio for pointing me in the right direction.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments