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

设置作为参数传递的TypeScript对象的默认值,typescript,Typescript,显然,如果这些是简单的参数,您可以使用: function sayName(params: {firstName: string; lastName: string = 'smith'}) { 在coffeescript中,您可以访问条件存在操作符,因此可以执行以下操作: function sayName(firstName: string, lastName = 'smith') { var name = firstName + lastName; alert(name);

显然,如果这些是简单的参数,您可以使用:

function sayName(params: {firstName: string; lastName: string = 'smith'}) {
在coffeescript中,您可以访问条件存在操作符,因此可以执行以下操作:

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

sayName('bob');
它编译为javascript:

param.lastName ?= 'smith'

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

if (param.lastName == null) {
    param.lastName = 'smith';
}
并使用它代替内联类型定义

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

    }
}
不幸的是,你不能这样做:

function sayName(name: Name) {
    alert(name.first + " " + name.last);
}

由于它只会在
name
undefined

时设置默认值,因此现在似乎有一种简单的方法。以下代码在TypeScript 1.5中工作:

函数sayName({first,last='Smith'}:{first:string;last?:string}):void{
const name=first+“”+last;
console.log(名称);
}
sayName({first:'Bob'});
诀窍是首先将要从参数对象中选取的键放在括号中,对于任何默认值,使用
key=value
。接下来是
和类型声明

这与您尝试执行的操作略有不同,因为您没有使用完整的
params
对象,而是使用了取消引用的变量

如果希望将任何内容传递给函数都是可选的,请为类型中的所有键添加一个
,并在类型声明后添加一个默认值
={}

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

} 
参数对象是上面许多答案的目标,Typescript现在有了适当的方法,使其更易于阅读和直观理解

解构基础:通过解构对象,可以按键名从对象中选择属性。您可以定义任意数量或任意数量的属性,默认值由
let{key=default}=object
的基本语法设置

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

sayName();
为参数对象编写接口、类型或类可以提高易读性

键入全名={
名字:字符串;
/**@default'Smith'*/
lastName?:字符串;
}
函数名称(参数:全名){
//设置参数对象的默认值
var{firstName,lastName='Smith'}=params;
//做事
var name=firstName+“”+lastName;
警报(名称);
}
//使用它
赛名({
名字:“鲍勃”

});这是一种不涉及长构造函数的很好的方法

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

//Compiles to:
var firstName = myParamsObject.firstName, 
_a = myParamsObject.lastName, 
lastName = _a === void 0 ? 'Smith' : _a;

Typescript现在支持默认参数:

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

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'}))

下面是一些可以尝试的方法,使用接口并使用默认值进行分解。请注意,“lastName”是可选的

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

sayName('Bob');

在不进行分解的情况下,可以创建默认参数并将其传入

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" })
接口名称{
名字:字符串;
lastName:string;
}
导出常量defaultName扩展忽略{
姓:“史密斯”
}
sayName({…defaultName,firstName:'Bob'})

您建议的解决方案
params.lastName=params.lastName | |“smith”
实际上相当不错-它处理空字符串、未定义字符串和空值。@SteveFenton和任何falsy。就姓氏而言,这没关系,但通常不是个好主意。这就是为什么Typescript将默认值转换为
if(typeof x==“undefined”){…}
。这并不是说你不知道,只是指出了OP的一般情况。@IngoBürk true,但由于
lastName?:string
它只能像SteveFenton说的那样“处理空字符串、未定义字符串和空值”。@AJP in Typescript,是的。但那只是编译时间。不管怎样,就像我说的,只是指出了一个一般情况:)在这里同意史蒂夫的观点。通常,最好使用一个配置参数,而不是10个参数。在本例中,
params.lastName=params.lastName | | smith'我使用的模式是否也可以重写此解决方案以使用类似“saynamestings”的接口/类?尽管如此,以这种方式分解参数会使IMO难以理解。您可以使用'as'关键字(我认为它更可读),如{first='Bob',last='Smith'}as{first?:string;last?:string}但理想情况下,您应该创建一个接口来处理这种情况…您还可以在参数中使用部分实用程序类型来处理类型部分,如果您有参数的预定义接口/类型,是否有方法将options对象传递给另一个函数?这如何适用于OP关于作为参数传递的TypeScript对象的默认值的问题?您应该展示一个带有对象参数的示例,它没有,但我在搜索如何在typescript中提供默认参数时发现了这个问题,没有一个答案解决了这个问题。在我注意到微妙的“object”参数澄清之前,我也发布了这个回复。@PWKad默认值设置在第二行和第三行,“Bob”和“Smith”最佳答案上,谢谢!我认为这是这个问题的最佳答案,应该标记为正确答案。我认为这是这个问题的最佳答案!
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" })
interface Name {
   firstName: string;
   lastName: string;
}

export const defaultName extends Omit<Name, 'firstName'> {
    lastName: 'Smith'
}

sayName({ ...defaultName, firstName: 'Bob' })