Typescript 如何使用接口键入函数参数?
我有以下接口Typescript 如何使用接口键入函数参数?,typescript,Typescript,我有以下接口 ITle { type: "A" | "B"; id: number; } 我想使用此接口键入函数的参数: const exampleFunc = (type, id) => {}; 有没有一种简单的方法可以做到这一点?谢谢 那么: ITle { type: "A" | "B"; id: number; } const exampleFunc = ({type, id
ITle {
type: "A" | "B";
id: number;
}
我想使用此接口键入函数的参数:
const exampleFunc = (type, id) => {};
有没有一种简单的方法可以做到这一点?谢谢 那么:
ITle {
type: "A" | "B";
id: number;
}
const exampleFunc = ({type, id}: ITle) => {};
这将迫使您使用对象调用函数,但我通常发现更可读:exampleFunc({type:“A”,id:1})
更新:或者,您可以将函数键入
type ExampleFunction = (type: 'A' | 'B', id: number) => void;
const exampleFunc: ExampleFunction = (type, id) => {};
没有可靠的编程方法可以将
ITle
转换为(x:“A”|“B”,y:number)=>void
,而不是(x:number,y:“A”|“B”)=>void
TypeScript通常将仅在属性声明顺序上不同的两种对象类型视为相同的类型。例如:
interface ITle {
type: "A" | "B";
id: number;
}
var foo: ITle;
var foo: { id: number, type: "A" | "B" }; // no error here
请注意,foo
的重新声明不会导致错误,这意味着编译器认为这两个带注释的类型是相同的。因此,您无法可靠地观察TypeScript对象类型中属性的顺序
而且,由于无法可靠地将ITle
转换为类似[“type”,“id”]
的有序列表,因此无法通过编程将其转换为参数按特定顺序排列的函数类型
(您可能已经注意到我一直在说“可靠”。在TypeScript中可以从对象类型中挑出属性顺序,但您确实不应该这样做,并且有许多警告。有关更多信息,请参阅。对于这个问题,我假设这是不可能的)
那你能做什么呢?好吧,如果你告诉编译器你想要什么顺序,它就会工作。这要求对象到函数的转换采用一组键,如下所示:
type ToFunc<T, K extends Array<keyof T>> =
(...args: { [I in keyof K]: T[Extract<K[I], keyof T>] }) => void;
这是我想要的,万岁
还有一件事。请注意,输出类型类似于
(args|u 0:“A”|“B”,args|u 1:number)=>void
,而不是类似于(键入:“A”|“B”,id:number)=>void
。也就是说,函数类型的参数名称与函数中的属性名称不对应。这是因为,与属性顺序一样,函数类型的参数名是不可观察的。只有参数名称不同的两种函数类型被视为相同的类型:
var bar: Func;
var bar: (type: "A" | "B", id: number) => void;
var bar: (fooby: "A" | "B", dooby: number) => void;
TypeScript类型中的函数参数名称仅用作文档提示,对类型系统的行为没有影响。如果您真的关心函数名(我认为您不应该这么做),可以使用a来告诉编译器给函数参数指定哪些标签:
type FuncLabeled = ToFunc<ITle, [type: "type", id: "id"]>;
/* type FuncLabeled = (type: "A" | "B", id: number) => void */
类型funclabel=ToFunc;
/*类型funclabel=(类型:“A”|“B”,id:number)=>void*/
但是这可能有点太多了,真的,因为在这一点上,每个属性名称都要写三次(一次用于接口,两次用于元组)
老实说,除非您的ITle
类型中有大量属性,或者其属性类型可能会经常更改,否则让编译器为您完成这项工作所付出的努力不太值得。你也可以手工写出类型(类型:“A”|“B”,id:number)=>void
const exampleFunc=(类型:ITle[“title”],id:ITle[“id”])=>{}代码>@JaredSmith嗯,它在使用接口,不是吗?后者只是一个建议,可能更适合OP的用例。
type FuncLabeled = ToFunc<ITle, [type: "type", id: "id"]>;
/* type FuncLabeled = (type: "A" | "B", id: number) => void */