Typescript 中的参数与选项

Fla*_*ken 3 arguments parameter-passing documentation-generation typescript

基于这个问题Multiple arguments vs. options 对象

我想知道这如何适用于 Typescript。我想做出这样的决定:

  • 预编译器/lint 给出的提示将尽可能相关。
  • 生成的文档也将尽可能干净。

我现在发现的利弊:

  • Typescript 可以很好地处理可选参数,但是我觉得依赖参数的顺序和拥有一长串参数并不方便。

  • option对象的使用很好,但需要为每个对象创建一个接口(?),在我的理解中,这会导致代码过载,我不知道会生成哪种文档/提示。

Dav*_*ret 7

在我看来,这同样适用于 TypeScript。不要依赖 IDE 来提示您代码的作用。最好让代码告诉您它的作用。

您拥有的参数越多,您的代码的可读性就越低

取以下代码:

sendMsg("Poem", "I sing of brooks, of blossoms, birds and bowers.", new Date(2015, 9, 20));
Run Code Online (Sandbox Code Playgroud)

我们也许可以说第一个参数是标题,第二个参数是正文,但是第三个参数有什么作用呢?这里的日期是什么意思?

我们必须查看函数签名才能看到:

function sendMsg(title: string, body: string, dateToSend = new Date())
Run Code Online (Sandbox Code Playgroud)

所以现在我们知道第三个参数是什么了,但是即使我们使用的是 TypeScript,我们仍然需要做一些调查并查看函数签名。或者,我们可以将鼠标移到开发环境的函数调用上来告诉我们,但这仍然不理想。

太多的参数会使更改变得困难并增加出错的机会

现在假设我们要添加一个新的必需日期参数,称为dateToSendAgain. 我们的函数签名更改为:

function sendMsg(title: string, body: string, dateToSendAgain: Date, dateToSend = new Date())
Run Code Online (Sandbox Code Playgroud)

这样做的一个问题是,我们原来的函数调用没有抛出编译错误,含义发生了变化:

// now creates a message with dateToSendAgain = new Date(2015, 9, 20)
// and dateToSend = new Date()
sendMsg("Poem", "I sing of brooks, of blossoms, birds and bowers.", new Date(2015, 9, 20));
Run Code Online (Sandbox Code Playgroud)

尽管我们最初打算dateToSend成为new Date(2015, 9, 20),但现在是new Date(),也许我们不想dateToSend成为new Date(2015, 9, 20)

改用具有属性的对象

我们可以通过让原始函数签名使用具有属性的对象来解决所有这些问题(请注意,不需要接口):

function sendMsg(options: { title: string; body: string; dateToSend?: Date; dateToSendAgain: Date; }) {
    // we now have to define our default values here though...
    // if we use destructuring it's not too bad:
    const {title, dateToSend = new Date()} = options;
    // ...rest of function body omitted...
}
Run Code Online (Sandbox Code Playgroud)

所以我们的原始代码应该是这样的:

sendMsg({
    title: "Poem", 
    body: "I sing of brooks, of blossoms, birds and bowers.", 
    dateToSend: new Date(2015, 9, 20)
});
Run Code Online (Sandbox Code Playgroud)

...这很容易快速了解正在发生的事情。

此外,当我们去 add 时dateToSendAgain,它会很容易,我们会得到一个编译错误,通知我们用新的必需属性更新我们所有的函数调用:

sendMsg({
    title: "Poem", 
    body: "I sing of brooks, of blossoms, birds and bowers.", 
    dateToSend: new Date(2015, 9, 20),
    dateToSendAgain: new Date(2015, 10, 20)
});
Run Code Online (Sandbox Code Playgroud)

建议

我的建议是:

  1. 当参数不是太多时使用多个参数,您可以通过查看函数名称来了解每个参数的含义。
  2. 否则使用具有属性的对象。
  3. 如果可读,将这两者混合在一起是可以的。

对象属性文档

TypeScript 使用 JSDoc来完成代码,因此您可以使用此语法来记录对象的属性。在此处阅读有关如何记录它的信息。

不幸的是,这似乎没有给我在带有 TS 1.6 的 Visual Studio 2013 中代码完成中的对象属性的描述。

使用接口似乎可以工作:

/**
 * The options for sendMsg
 */
interface SendMsgOptions {
    /**
    * The title of the message
    */
    title: string;
    // etc...
}
Run Code Online (Sandbox Code Playgroud)

更改函数头:

function sendMsg(options: SendMsgOptions)
Run Code Online (Sandbox Code Playgroud)

然后在使用的时候就可以在代码补全中看到注释了:

消息选项代码完成