Type System?

Seulyi Yoo·2022년 7월 14일
0

TypeScript

목록 보기
19/42
post-thumbnail

Type System?

  • Compiler 에게 사용하는 타입을 명시적으로 지정하는 시스템
  • Compiler 가 자동으로 타입을 추론하는 시스템

Type System of TypeScript?

  • 타입을 명시적으로 지정할 수 있다.
  • 타입을 명시적으로 지정하지 않으면, TypeScript Compiler 가 자동으로 타입을 추론

자신의 코드에서 해당 함수를 사용하는 사용자 - 형태를 정해둔 함수 - 해당 함수를 구현하는 구현자

타입이란 해당 변수가 할 수 있는 일을 결정함

// JavaScript

// f1 이라는 함수의 body 에서는 a 를 사용할 것
// a 가 할 수 있는 일은 a 의 타입이 결정함

function f1(a) {
	return a;
}

함수 사용법에 대한 오해를 야기하는 JavaScript

// JavaScript

// (f2 실행의 결과가 NaN 을 의도한 것이 아니라면)
// 이 함수의 작성자는 매개변수 a 가 number 타입이라는 가정으로 함수를 작성

function f2(a) {
	return a * 38;
}

// 사용자는 사용법을 숙지하지 않은 채, 문자열을 사용하여 함수를 실행

console.log(f2(10)); // 380
console.log(f2("Mark")); // NaN

TypeScript 의 추론에 의지하는 경우

// TypeScript

// a 의 타입을 명시적으로 지정하지 않은 경우이기 때문에 a 는 any 로 추론됨
// 함수 return 타입은 number 로 추론됨 (NaN 은 number)

function f3(a) {
	return a * 38;
}

// 사용자는 a 가 any 이기 때문에, 사용법에 맞게 문자열을 사용하여 함수를 실행

console.log(f2(10)); // 380
console.log(f2("Mark") + 5); // NaN

noImplicitAny 옵션을 켜면

타입을 명시적으로 지정하지 않은 경우,

TypeScript 가 추론 중 ‘any’ 라고 판단하게 되면,

컴파일 에러를 발생시켜 명시적으로 지정하도록 유도한다.

noImplicitAny 에 의한 방어

// TypeScript

// error TS7006: Parameter 'a' implicitly has an 'any' type.

function f3(a) {
	 return a * 38;
}

// 사용자의 코드를 실행할 수 없음. 컴파일이 정상적으로 마무리 될 수 있도록 수정해야 함

console.log(f3(10));
console.log(f2("Mark") + 5); 

number 타입으로 추론된 타입

// TypeScript

// 매개변수로의 타입은 명시적으로 지정
// 명시적으로 지정하지 않은 함수의 리턴 타입은 number 로 추론

function f4(a: number) {
	if(a > 0) {
		return a * 38;
	}
}

// 사용자는 사용법에 맞게 숫자형을 사용하여 함수를 실행
// 해당 함수의 리턴 타입은 number 이기 때문에, 타입에 따르면 이어진 연산을 바로 할 수 있음
// 실제 undefined + 5 가 실행되어 NaN 출력

console.log(f4(5)); // 190
console.log(f4(-5) + 5); // NaN

strictNullChecks 옵션을 켜면

모든 타입에 자동으로 포함되어 있는 ‘null’ 과 ‘undefined’ 를 제거해 줌

// TypeScript

// 매개변수로의 타입은 명시적으로 지정
// 명시적으로 지정하지 않은 함수의 리턴 타입은 number | undefined 로 추론

function f4(a: number) {
	if(a > 0) {
		return a * 38;
	}
}

// 사용자는 사용법에 맞게 숫자형을 사용하여 함수를 실행
// 해당 함수의 리턴 타입은 number | undefined 이기 때문에, 
// 타입에 따르면 이어진 연산을 바로 할 수 없음
// 컴파일 에러를 고쳐야하기 때문에 사용자와 작성자가 의논해야 함

console.log(f4(5)); 
console.log(f4(-5) + 5); // error TS2532: Object si possibly 'undefined'.

명시적으로 리턴 타입을 지정해야할까?

// TypeScript

// 매개변수의 타입과 함수의 리턴 타입을 명시적으로 지정
// 실제 삼수 구현부의 리턴 타입과 명시적으로 지정한 타입이 일치하지 않아 컴파일 에러가 발생

// error TS2366: Function lacks ending return statement and return type does not ...

function f5(a: number): number {
	if( a > 0 ) {
		return a * 38;
	}
}

noImplicitReturns 옵션을 켜면

함수 내에서 모든 코드가 값을 리턴하지 않으면, 컴파일 에러가 발생

// TypeScript

// 모든 코드에서 리턴을 직접해야 함.
// if 가 아닌 경우 return 을 직접 하지 않고 코드가 종료

// error TS7030: Not all code paths return a value.
function f5(a: number) {
	if( a > 0 ) {
		return a * 38;	
	}
}

매개변수에 object 가 들어오는 경우

// JavaScript

function f6(a) {
	return `이름은 ${a.name} 이고, 연령대는 ${ Math.floor(a.age / 10) * 10}대 입니다.`;
}

console.log(f6({ name: "Mark", age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f6("Mark")); // 이름은 undefined 이고, 연령대는 NaN대 입니다.

object litertal type

// TypeScript

function f7(a: { name: string; age: number }): string {
	return `이름은 ${a.name} 이고, 연령대는 ${ Math.floor(a.age / 10) * 10}대 입니다.`;
}

console.log(f7({ name: "Mark", age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f6("Mark")); 
// error TS2345: Argument of type 'string' is not assignable to parameter of type '{ name: string; age: number }'.

나만의 타입을 만드는 방법

// TypeScript

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

type PersonTypeAlias = {
  name: string;
  age: number;
};

function f8(a: PersonInterface): string {
  return `이름은 ${a.name} 이고, 연령대는 ${ Math.floor(a.age / 10) * 10}대 입니다.`;
}

console.log(f8({ name: "Mark", age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f8('Mark'));
// error TS2345: Argument of type 'string' is not assignable to parameter of type '{ name: string; age: number }'.
profile
성장하는 개발자 유슬이 입니다!

0개의 댓글