设置作为参数传递的TypeScript对象的默认值

AJP*_*AJP 147 typescript

function sayName(params: {firstName: string; lastName?: string}) {
    params.lastName = params.lastName || 'smith';  // <<-- any better alternative to this?
    var name = params.firstName + params.lastName
    alert(name);
}

sayName({firstName: 'bob'});
Run Code Online (Sandbox Code Playgroud)

我曾经想象过这样的事情可能有用:

function sayName(params: {firstName: string; lastName: string = 'smith'}) {
Run Code Online (Sandbox Code Playgroud)

显然,如果这些是明确的论据,你可以这样做:

function sayName(firstName: string, lastName = 'smith') {
    var name = firstName + lastName;
    alert(name);
}

sayName('bob');
Run Code Online (Sandbox Code Playgroud)

在coffeescript中,您可以访问条件存在运算符,因此可以执行以下操作:

param.lastName ?= 'smith'
Run Code Online (Sandbox Code Playgroud)

哪个编译成javascript:

if (param.lastName == null) {
    param.lastName = 'smith';
}
Run Code Online (Sandbox Code Playgroud)

jpa*_*dvo 161

实际上,现在似乎有一种简单的方法.以下代码适用于TypeScript 1.5:

function sayName({first,last='Smith'}: {first: string; last?: string}){
    var name = first + " " + last;
    alert(name);
}

sayName({firstName: 'Bob'});
Run Code Online (Sandbox Code Playgroud)

诀窍是首先在括号中放入要从参数对象中选择的键,key=value对于任何默认值.使用:和类型声明跟随它.

这与您尝试执行的操作略有不同,因为params您不是拥有完整的对象,而是使用解除引用的变量.

如果要使其可选地将任何内容传递给函数,请?为类型中的所有键添加一个,并={}在类型声明后添加默认值:

function sayName({first='Bob',last='Smith'}: {first?: string; last?: string}={}){
    var name = first + " " + last;
    alert(name);
}

sayName();
Run Code Online (Sandbox Code Playgroud)

  • 是否也可以重写此解决方案以使用诸如“sayNameSettings”之类的接口/类? (4认同)
  • 虽然这有效,但以这种方式解构论证使得很难跟随IMO. (3认同)
  • 有没有办法将选项对象传递给另一个函数? (3认同)
  • @Rainning 这有点棘手,但这是整个参数对象的默认值。它允许您在不提供*任何*参数的情况下调用该函数。因为就在那里,您可以像这样调用这个函数:`sayName()`。如果删除`={}`,则至少必须传入一个空对象。 (3认同)
  • 我认为定义类型更容易且更具可读性:`export type NameBits = {first?: string; 最后?:字符串;};` 您可以通过决定在赋值中赋予默认值的内容来确定哪些内容是可选的。类型 def 中的可选标志“?”使得可以声明一个缺少该类型**的那些属性的对象。这样您就可以按名称传递参数对象。`function sayName( nameBits: NameBits = { first: "Bob", Last: "Smith" } ) { /* 如果需要,可以解构命名变量 */ const {first, last } = nameBits; 警报(\`${第一个} ${最后}\` ); }` (2认同)
  • 这的可读性很糟糕。 (2认同)

enc*_*est 42

Typescript现在支持默认参数:

https://www.typescriptlang.org/docs/handbook/functions.html

此外,添加默认值允许您省略类型声明,因为它可以从默认值推断:

function sayName(firstName: string, lastName = "Smith") {
  const name = firstName + ' ' + lastName;
  alert(name);
}

sayName('Bob');
Run Code Online (Sandbox Code Playgroud)

  • 这如何适用于OP关于作为参数传递的TypeScript对象的默认值的问题?您应该显示一个带有对象参数的示例. (8认同)
  • 它没有,但是当我在搜索如何在打字稿中提供默认参数时,我发现了这个问题,并且没有一个答案解决了这个问题.在我注意到微妙的"对象"参数澄清之前,我也发布了这个回复. (6认同)

Wir*_*rie 23

不,TypeScript没有一种自然的方法来为一个对象的属性设置默认值,就像一个对象具有默认值而另一个没有默认值.您可以定义更丰富的结构:

class Name {
    constructor(public first : string, 
        public last: string = "Smith") {

    }
}
Run Code Online (Sandbox Code Playgroud)

并使用它代替内联类型定义.

function sayName(name: Name) {
    alert(name.first + " " + name.last);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,你不能做这样的事情:

function sayName(name : { first: string; last?:string } 
       /* and then assign a default object matching the signature */  
       = { first: null, last: 'Smith' }) {

} 
Run Code Online (Sandbox Code Playgroud)

由于它只会设置默认值,如果nameundefined.

  • 我认为这是这个问题的最佳答案,应该标记为正确答案。 (2认同)

Ben*_*son 22

对象解构参数对象是上面的许多答案的目标,而现在,Typescript已经有了方法,使其更容易阅读和直观理解.

解构基础:通过解构对象,您可以按键名称从对象中选择属性.您可以定义您喜欢的少数或多个属性,默认值由基本语法设置let {key = default} = object.

let {firstName, lastName = 'Smith'} = myParamsObject;

//Compiles to:
var firstName = myParamsObject.firstName, 
_a = myParamsObject.lastName, 
lastName = _a === void 0 ? 'Smith' : _a;
Run Code Online (Sandbox Code Playgroud)

为参数对象编写接口,类型或类可以提高易读性.

type FullName = {
  firstName: string;
   
  /** @default 'Smith' */
  lastName ? : string;
}

function sayName(params: FullName) {

  // Set defaults for parameter object
  var { firstName, lastName = 'Smith'} = params;

  // Do Stuff
  var name = firstName + " " + lastName;
  alert(name);
}

// Use it
sayName({
  firstName: 'Bob'
});
Run Code Online (Sandbox Code Playgroud)

  • @DollarAkshay:为什么在函数体中隐藏函数_parameter_的默认值更有意义? (7认同)
  • 我想这就是这个问题最好的答案! (5认同)
  • 这比公认的答案好得多。函数体内的破坏比参数本身更有意义 (4认同)

Cam*_*ron 17

这可能是一个不需要长构造函数的好方法

class Person {
    firstName?: string = 'Bob';
    lastName?: string = 'Smith';

    // Pass in this class as the required params
    constructor(params: Person) {
        // object.assign will overwrite defaults if params exist
        Object.assign(this, params)
    }
}

// you can still use the typing 
function sayName(params: Person){ 
    let name = params.firstName + params.lastName
    alert(name)
}

// you do have to call new but for my use case this felt better
sayName(new Person({firstName: 'Gordon'}))
sayName(new Person({lastName: 'Thomas'}))
Run Code Online (Sandbox Code Playgroud)

  • @PWKad默认设置在第二行和第三行,"Bob"和"Smith" (2认同)

Ben*_*Dev 5

这里有一些可以尝试的方法,使用接口和使用默认值进行解构。请注意,“姓氏”是可选的。

interface IName {
  firstName: string
  lastName?: string
}

function sayName(params: IName) {
  const { firstName, lastName = "Smith" } = params
  const fullName = `${firstName} ${lastName}`

  console.log("FullName-> ", fullName)
}

sayName({ firstName: "Bob" })
Run Code Online (Sandbox Code Playgroud)