인수로 전달 된 TypeScript 객체의 기본값 설정


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

나는 이런 식으로 작동한다고 상상했다.

function sayName(params: {firstName: string; lastName: string = 'smith'}) {

분명히 이것이 명백한 주장이라면 다음과 같이 할 수 있습니다.

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

sayName('bob');

그리고 coffeescript에서 조건부 존재 연산자에 액세스 할 수 있습니다.

param.lastName ?= 'smith'

다음은 자바 스크립트로 컴파일됩니다.

if (param.lastName == null) {
    param.lastName = 'smith';
}

제안 된 솔루션 params.lastName = params.lastName || 'smith';은 실제로 다소 괜찮습니다. 빈 문자열, 정의되지 않은 문자열 및 null 값을 처리합니다.
— Fenton

@SteveFenton 그리고 잘못된 것. 성의 경우에는 문제가 없지만 일반적으로 좋은 생각은 아닙니다. 이것이 Typescript가 기본값을로 변환하는 이유 if(typeof x === "undefined") { … }입니다. 그 사실을 모르는 것이 아니라 OP의 일반적인 사례를 지적하십시오.
— Ingo Bürk

1
@ IngoBürk는 사실이지만 lastName?: stringSteveFenton이 말한 것처럼 "빈 문자열, 정의되지 않은 문자열 및 null 값을 처리합니다".
— AJP

Typescript 내의 @AJP, 예. 그러나 그것은 단지 컴파일 타임입니다. 어느 쪽이든, 내가 말했듯이, 일반적인 사례 시나리오를 지적합니다 :)
— Ingo Bürk

2
스티브와 동의 해 일반적으로 10 개의 인수 대신 단일 구성 인수를 사용하는 것이 좋습니다. 이 경우 params.lastName = params.lastName || 'smith';에 내가 사용하는 패턴 이있다
— basarat

답변:


211

실제로는 간단한 방법이 있습니다. 다음 코드는 TypeScript 1.5에서 작동합니다.

function sayName({ first, last = 'Smith' }: {first: string; last?: string }): void {
  const name = first + ' ' + last;
  console.log(name);
}

sayName({ first: 'Bob' });

트릭은 먼저 key=value기본적으로 인수 객체에서 선택하려는 키를 괄호로 묶는 것 입니다. 와 그 수행 :과 유형 선언을.

이것은 온전한 params객체 대신에 역 참조 된 변수를 가지고 있기 때문에 수행하려는 것과 약간 다릅니다 .

선택적으로 함수에 무엇이든 전달 ?하려면 유형의 모든 키에 대해 a 를 추가 ={}하고 유형 선언 뒤에 기본값을 추가하십시오 .

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

sayName();

이 솔루션은 완전히 변형 된 매개 변수를 보여 주기 때문에 인터 네팅 코드 힌트 / 지능형 기능을 제공합니다. 예제와 같이 몇 가지 매개 변수가있는 설정 객체에서 해당 스타일을 보지 못할 것입니다.
— WiredPrairie

3
대신 "sayNameSettings"와 같은 인터페이스 / 클래스를 사용하도록이 솔루션을 다시 작성할 수 있습니까?
— Stef Heyenrath

4
이것이 작동하는 동안 이러한 방식으로 인수를 파기하면 IMO를 따르기가 어렵습니다.
— PW Kad

1
{first = 'Bob', last = 'Smith'}와 같은 'as'키워드를 사용하면 {first ?: string; last ?: string} 그러나 이상적으로이 경우를 처리하기위한 인터페이스를 만들어야합니다.
— Frohlich

1
옵션 객체를 다른 함수로 전달하는 방법이 있습니까?
— Dylanthepiguy

53

Typescript는 현재 기본 매개 변수를 지원합니다.

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

또한 기본값을 추가하면 형식 선언을 기본값에서 유추 할 수 있으므로 형식 선언을 생략 할 수 있습니다.

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

sayName('Bob');

22
인수로 전달 된 TypeScript 개체의 기본값과 관련하여 OP의 질문에 어떻게 적용됩니까? 객체 인수가있는 예제를 보여 주어야합니다.
— demisx

9
그렇지는 않지만 일반적으로 typescript에서 기본 매개 변수를 제공하는 방법을 검색 할 때이 질문을 찾았지만 그 대답은 없습니다. 또한 미묘한 "객체"매개 변수가 명확 해지기 전에이 응답을 게시했습니다.
— encrest

29

매개 변수 객체를 객체 제거 하는 것은 위의 많은 답변이 목표로하고 있으며 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;

매개 변수 객체에 대한 인터페이스, 유형 또는 클래스를 작성하면 가독성이 향상됩니다.

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


3
이것이 이것이 질문에 대한 가장 좋은 대답이라고 생각합니다!
— Gezim

24

아니요, TypeScript에는 하나의 기본값이 있고 다른 하나는 그렇지 않은 것처럼 정의 된 객체의 속성에 대한 기본값을 설정하는 자연스러운 방법이 없습니다. 보다 풍부한 구조를 정의 할 수 있습니다.

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

    }
}

인라인 유형 정의 대신 사용하십시오.

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

불행히도 이와 같은 것을 할 수 없습니다 :

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

} 

namewas 인 경우에만 기본값을 설정합니다 undefined.


이것이이 질문에 대한 최선의 답변이라고 생각하며 정답으로 표시해야합니다.
— kapad

16

이것은 긴 생성자를 포함하지 않는 좋은 방법 일 수 있습니다.

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

2
@PWKad 기본값은 두 번째 및 세 번째 줄 "Bob"및 "Smith"에 설정되어 있습니다
— Cameron

3

다음은 인터페이스를 사용하고 기본값으로 파괴하는 것입니다. "lastName"은 선택 사항입니다.

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

0

파괴하지 않고도 기본 매개 변수를 만들어 전달할 수 있습니다

interface Name {
   firstName: string;
   lastName: string;
}

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

sayName({ ...defaultName, firstName: 'Bob' })
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.