[Typescript] 초과 프로퍼티와 선택적 프로퍼티

js43o·2021년 11월 19일
0

초과 프로퍼티 검사

객체 리터럴은 다른 변수에 할당할 때나 인수로 전달할 때, 초과 프로퍼티 검사를 받는다.

interface Person {
    name: string;
    age: number;
}

function getName(person: Person): string {
    if (person.name)
        return person.name;
    else
        return "no name";
}

const noman = {
    name: "Noman",
    age: 18,
    favorite: "movie"
};

getName(noman);
getName({ name: "NOMAN", age: 18, favorite: "movie" });	// 에러

요구하는 인터페이스인 Person에 명시되지 않은 프로퍼티를 갖고 있기에 에러가 발생했다.
그러나 똑같은 객체를 변수에 할당한 뒤 전달하면 에러가 발생하지 않는다.

getname({ name: "NOMAN", age: 18, favorite: "movie" } as Person);

또는 타입 단언 as 문법을 이용하여 초과 프로퍼티 검사를 피할 수 있다.

선택적 프로퍼티

프로퍼티를 필수가 아닌 선택적으로 할당하도록 정의할 수 있다.

interface Person {
    name?: string;
    age?: number;
}

이 경우 nameage 프로퍼티는 선택적 프로퍼티가 된다. 즉, 해당 인터페이스를 이용하여 정의할 때 선택적 프로퍼티는 있어도 되고 없어도 된다.

const man = {
    name: "Man",
    favorite: "war"
};

const girl = {};

const noman = {
    favorite: "movie"
};

getName(man);
getName(girl);

getName(noman); // 에러
getName(noman as Person);

noman의 경우, Person에 정의된 선택적 프로퍼티가 하나도 없으며 초과 프로퍼티 favorite를 가지고 있다. 이때는 객체 리터럴이 아닌 변수를 전달했음에도 에러가 발생했다.
이런 방법으로 초과 프로퍼티 검사를 피하고 싶을 때는 인터페이스에 정의된 프로퍼티를 한 개 이상 가지고 있어야 한다.

그렇지 않다면 타입 단언을 사용하거나, 문자열 인덱스 서명을 이용할 수 있다.

문자열 인덱스 서명

interface Person {
    name?: string;
    age?: number;
    [propname: string]: any; // string 타입의 index에 any 타입의 값을 할당함
}

const noman: Person = {
    name: "Noman",
    favorite: "movie"
};

console.log(noman["favorite"]); // "movie"

타입스크립트에서 인덱스 서명의 타입은 string 또는 number여야 한다.

interface Person {
    name?: string; // 에러
    age: number; // 에러
    favorite: string;
    [propname: string]: string;
}

인덱스로 할당할 값의 타입이 any가 아닌 경우, 인터페이스에 명시된 모든 프로퍼티는 모두 해당 타입을 따라야 한다. 또한, 선택적 프로퍼티 name?: string를 사용한 경우, string | undefined 타입을 인덱스 키의 타입인 string에 할당할 수 없다 는 에러가 발생한다.

profile
공부용 블로그

0개의 댓글