【问题标题】:Using named parameters JavaScript (based on typescript)使用命名参数 JavaScript(基于 typescript)
【发布时间】:2022-04-26 16:36:48
【问题描述】:

我有问题,在 TypeScript 中使用命名参数时,我知道它不支持我在 TS 中使用它的方式。 但是我怎么能

打字稿:

SomeFunction(name1: boolean, name2: boolean, name3: boolean, name4: boolean) //will occur only 1 time, so the change should be in typescript

JavaScript:

$(function () {
     ...SomeFunction({name1:false, name2:false, name3:false, name4:true}); //will occur 100 times    
});

我在看(这没有成功):

Named parameters in javascript

How can I add optional named parameters to a TypeScript function parameter?

如何在 TypeScript 中使用 JavaScript 中的命名参数?

我想知道的是,VS2015 在使用命名参数时没有显示语法错误,就像我在 TypeScript 中使用它的方式一样......

ps.:我使用的是 TS 2.1

【问题讨论】:

  • 好吧,调用时命名参数在 TS 和 JS 中都不存在。为什么您链接的其他解决方案不适合您?他们应该。
  • @deceze stackoverflow.com/questions/11796093/… Ray Perea 的帖子(实际上是一个 JS 对象)
  • not对你有什么作用……?
  • 进入打字稿对象会看起来很奇怪,看看pasteboard.co/vNZ5OEg16.png(类似例子)
  • 传递对象与命名参数不同。可以修改对象(即某种 ref 参数。可以在本地修改参数,但在返回时看不到该更改;它是本地参数。

标签: javascript typescript


【解决方案1】:

真正的命名参数在 JavaScript 和 TypeScript 中都不存在,但你可以使用 destructuringsimulate named parameters:

interface Names {
    name1: boolean
    name2: boolean
    name3: boolean
    name4: boolean
}

function myFunction({name1, name2, name3, name4}: Names) {
    // name1, etc. are boolean
}

注意:Names 类型实际上是可选的。以下 JavaScript 代码(无需键入)在 TS 中有效:

function myFunction({name1, name2, name3, name4}) {
    // name1, etc. are of type any
}

【讨论】:

  • 最后一部分,虽然是对的,但它不是真正的 Typescript,它是这里的主要问题,而不是 javascript。
【解决方案2】:

获得接近“命名参数”的唯一方法是使用单个对象参数:

type SomeFunctionParams = {
    name1: boolean;
    name2: boolean;
    name3: boolean;
    name4: boolean;
}

SomeFunction(params: SomeFunctionParams) { ... }

然后:

$(function () {
    SomeFunction({
        name1:false, 
        name2:false, 
        name3:false, 
        name4:true
    });  
});

【讨论】:

    【解决方案3】:

    匿名界面

    我只是想指出,您也可以在参数列表中声明没有名称的类型,如下所示,这样我们就不用输入interface myfuncArgs

    它仍然迫使我重新输入每个参数,这很痛苦,但我现在不知道如何避免这种情况。

    const assert = require('assert')
    
    function myfunc({
        myInt,
        myString,
      }: {
        myInt: number,
        myString?: string,
      }
    ) {
      return `${myInt} ${myString}`
    }
    
    assert.strictEqual(
      myfunc({
        myInt: 1,
        myString: 'abc',
      }),
      '1 abc'
    )
    
    assert.strictEqual(
      myfunc({
        myInt: 1,
      }),
      '1 undefined'
    )
    
    // Fails as desired since myInt is not optional and was not given.
    //assert.strictEqual(
    //  myfunc({
    //    myString: 'abc',
    //  }),
    //  'unefined abc'
    //)
    
    // Fails as desired since wrong type of myInt.
    //assert.strictEqual(
    //  myfunc({
    //    myInt: '1',
    //    myString: 'abc',
    //  }),
    //  '1 abc'
    //)
    

    编译运行:

    npx tsc main.ts
    node main.js
    

    测试于:

      "dependencies": {
        "@types/node": "^16.11.13",
        "typescript": "^4.5.4"
      }
    

    相关:

    当有可选参数时,您通常需要显式 interface

    如果任何道具是可选的,是以下示例的情况,并且可能是大多数“选项”参数,那么您可能希望显式定义类型,如下所述:https://stackoverflow.com/a/42108988/895245,因为很可能调用者迟早会需要它来逐步构建选项对象,相关:How do I dynamically assign properties to an object in TypeScript?

    例如考虑以下工作代码:

    const assert = require('assert')
    
    interface myfuncOpts {
      myInt: number,
      myString?: string,
    }
    
    function myfunc({
      myInt,
      myString,
    }: myfuncOpts) {
      return `${myInt} ${myString}`
    }
    
    const opts: myfuncOpts = { myInt: 1 }
    if (process.argv.length > 2) {
      opts.myString = 'abc'
    }
    
    assert.strictEqual(
      myfunc(opts),
      '1 abc'
    )
    

    如果我们已经定义了myfuncOpts inline,那么我们将无法执行const opts: myfuncOpts,然后opts.myString = 'abc' 将失败,因为:

    const opts = { myInt: 1 }
    if (process.argv.length > 2) {
      opts.myString = 'abc'
    }
    

    opts的类型是从初始化推导出来的,不包含myString

    我希望 TypeScript 能够实现一个系统,您可以在其中说“使用此类函数的此类参数的类型”。然后我们可以使用内联参数类型定义,但仍然以某种方式引用类型,它将是 Nirvana。

    【讨论】:

      【解决方案4】:

      简单的解决方案是使用有意义命名的局部变量:

      var mungo: boolean=true, mary: boolean=true, and: boolean=true, midge: boolean=true;
      
      zapOn(mungo, mary, and, midge);
      

      人们:这只是第一步简单的解决方案.. 遵循测试驱动开发的原则:测试失败,让它工作 - 测试绿色(这个建议),重构(如果需要,将本地人放在一个对象中并通过那个函数)

      如果你在 Typescript 中这样定义 zapOn 函数:zapOn({mungo, mary=false, midge, and}: TVInterface) {...} where TVInterface {mary?: boolean, mungo: boolean, and: boolean, midge: boolean} 并传递 tv 对象 = {mary: undefined, mungo: mungo, and: and, midge: midge} 即 zapOn(tv) 由于函数参数级别的对象解构,函数中的变量/参数将正确排列up.. 在“mary”参数的情况下,我们还将默认值设置为 false ?

      【讨论】:

      • 不是name参数调用的。如果函数参数顺序发生变化会发生什么!或者用户写的顺序不正确,建议你的答案干净编程,但不要通过name参数调用函数。
      猜你喜欢
      • 2013-02-08
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 2018-09-05
      相关资源
      最近更新 更多