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 */