type guard
는 조건문을 통해서 변수가 가질 수 있는 타입의 개수를 줄여나가게 해줌.
type alphanumeric = string | number;
function add(a: alphanumeric, b: alphanumeric) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
throw new Error('Invalid arguments. Both arguments must be either numbers or strings.');
}
위 코드에서 2개의 인자가 모두 number
혹은 string
인지 확인하고 각각에 맞는 리턴을 해줌. 만약에 2개의 인자가 모두 number
, string
이 아닌경우에는 에러나오게함.
typeof
를 통해서 인자의 타입을 알아낼 수 있음.
class Customer {
isCreditAllowed(): boolean {
// ...
return true;
}
}
class Supplier {
isInShortList(): boolean {
// ...
return true;
}
}
type BusinessPartner = Customer | Supplier;
function signContract(partner: BusinessPartner) : string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
}
if (partner instanceof Supplier) {
message = partner.isInShortList() ? 'Sign a new contract the supplier' : 'Need to evaluate further';
}
return message;
}
let customer = new Customer();
let supplier = new Supplier();
console.log(signContract(customer));
console.log(signContract(supplier));
// Output :
Sign a new contract with the customer
Sign a new contract the supplier
위에서 BusinessPartner
를 parameter로 받는 signContract()
함수를 만들고, 인자로 각각의 인스턴스를 넣었을때 instanceof
로 인스턴스인지 아닌지 알 수 있음.
function signContract(partner: BusinessPartner) : string {
let message: string;
if (partner instanceof Customer) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
return message;
}
위 처럼 if...else로 해도 else를 탔을때 Customer
의 인스턴스가 아닐 경우에 Customer
의 인스턴스가 아닌 모든 것이 아닌 Supplier
의 인스턴스여서 else를 타는것.
in
으로 객체안에 property가 있는지 확인 가능함.
function signContract(partner: BusinessPartner) : string {
let message: string;
if ('isCreditAllowed' in partner) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
// must be Supplier
message = partner.isInShortList() ? 'Sign a new contract the supplier ' : 'Need to evaluate further';
}
return message;
}
사용자 지정 타입 가드는 타입 가드를 정하거나 함수를 사용할때 타입스크립트가 타입을 추론하는데 도움을ㅈ 줌.
사용자 지정 타입 가드 함수는 단순히 arge is aType
을 리턴하는 함수임.
function isCustomer(partner: any): partner is Customer {
return partner instanceof Customer;
}
function signContract(partner: BusinessPartner): string {
let message: string;
if (isCustomer(partner)) {
message = partner.isCreditAllowed() ? 'Sign a new contract with the customer' : 'Credit issue';
} else {
message = partner.isInShortList() ? 'Sign a new contract with the supplier' : 'Need to evaluate further';
}
return message;
}
위에서 isCustomer()
는 사용자 지정 타입 가드 함수임.
boolean
대신에 is
를 사용하면 아래에서 isString()
이 true
를 리턴했을때 타입스크립트가 타입 가드가 블럭인 if문 안에서 foo
의 타입을 string
으로 생각함.
예시1은 컴파일 에러도 없고 런타임 에러도 없음.
// 예시 1
function isString(test: any): test is string{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
}
example("hello world");
예시2는 컴파일에러와 런타임에러를 가짐. 타입스크립트가 타입을 string
으로 좁혔으므로 toExponetial
은 string
에 속하는 메소드가 아니기 때문임.
// 예시 2
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
예시 3은 컴파일 에러는 없지만 런타임에러는 생김. 타입스크립트가 if문 안의 타입만 string
으로 좁혔기 때문에 foo.toExponential
에서의 foo
는 타입스크립트가 string
이라고 생각하지 않으므로 컴파일에러가 발생하지는 않지만 저 메소드는 string
의 메소드가 아니기 때문에 런타임에러가 생김.
// 예시 3
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
}
console.log(foo.toExponential(2));
}
예시 4처럼 test is string
(type predicate)를 사용하지 않고 boolean
을 사용하면 타입스트립트는 타입 가드된 블록에서 type narrow를 하지 않기 때문에 컴파일에러는 없지만 런타임에러가 나옴.
// 예시 4
function isString(test: any): boolean{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length);
console.log(foo.toExponential(2));
}
}
- 타입가드는 조건문들 통해서 변수가 가지는 타입을 줄여나감
typeof
나instanceof
연산자로 조건문에서 타입 가드를 구현가능함