I'm currently experimenting with TypeScript to achieve narrowed types when dealing with index signatures and union types without explicitly discriminating them, such as using a switch case statement.
The issue arises in the code snippet below when attempting to call the doubleFn variable with the shape. Although at runtime the correct shape (circle) is returned and the doubleFn function for doubling the radius is inferred correctly, an error is thrown during compilation.
My question is, Is there a way to narrow the type of doubleFn so that it recognizes it as the corresponding pair to the provided shape?
Link to TypeScript playground with the same code
enum Shapes {
Circle,
Square,
}
interface ShapeProperties {
[Shapes.Circle]: {
radius: number;
};
[Shapes.Square]: {
length: number;
};
}
type FunctionsType = {
[key in Shapes]: (a: ShapeProperties[key]) => ShapeProperties[key];
};
const doubleFunctions: FunctionsType = {
[Shapes.Circle]: (circleProps: ShapeProperties[Shapes.Circle]) => ({
radius: circleProps.radius * 2,
}),
[Shapes.Square]: (squareProps: ShapeProperties[Shapes.Square]) => ({
length: squareProps.length * 2,
}),
};
interface Circle {
type: Shapes.Circle;
props: ShapeProperties[Shapes.Circle];
}
interface Square {
type: Shapes.Square;
props: ShapeProperties[Shapes.Square];
}
type Shape = Circle | Square;
function getShape(): Shape {
return { type: Shapes.Circle, props: { radius: 5 } };
}
const shape = getShape();
const doubleFn = doubleFunctions[shape.type];
doubleFn(shape.props);