我正在尝试使用条件类型来链接函数中的两个参数,但在定义函数时我无法整理出链接 2 个参数的方法。以下是简化示例或 the live version .
type Circle = { type: "circle"; data: { radius: number } };
type Rect = { type: "rect"; data: { width: number; height: number } };
type DefinedShape = Circle | Rect;
type FilterShapeByType<Shape, Type> = Shape extends { type: Type }
? Shape
: never;
type DrawShape = <T extends DefinedShape["type"]>(
type: T,
data: FilterShapeByType<DefinedShape, T>["data"]
) => void;
let drawShape1: DrawShape = () => {};
drawShape1("rect", { height: 12, width: 22 }); // pass
drawShape1("rect", { height: 12, width: 22, radius: 23 }); // failed, radius is not defined
drawShape1("circle", { radius: 12 }); // pass
drawShape1("circle", { radius: 12, len: 23 }); // failed, len is not defined
const drawShape2: DrawShape = (type, data) => {
switch (type) {
case "circle":
console.log(data.radius); // failed, Property 'radius' does not exist on type '(FilterShapeByType<Circle, T> | FilterShapeByType<Rect, T>)["data"]'.
break;
case "rect":
console.log(data.height, data.width);
break;
}
};
最初的目标是链接DrawShape
函数中的两个参数,即当type
为circle
时,data
应该是 {radius: number}
。我使用条件类型 FilterShapeByType
对其进行排序。
在我尝试定义函数 drawShape2
之前一切正常。我期望当我为 circle
的 type
使用 switch 时, typescript 应该足够聪明,可以假设 data
应该是 Circle[ 'data']
,但它没有。想知道有没有简单的自动制作?
最佳答案
只有一个技巧。不要告诉任何人:D
只需使用命名元组
function drawShape2(...args: [type: 'circle', data: Circle['data']] | [type: 'rect', data: Rect['data']]) {
switch (args[0]) {
case "circle":
const [type1, data1] = args;
break;
case "rect":
const [type2, data2] = args
break;
}
};
关于typescript - 在函数中使用条件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66744006/