타입 안정성
타입스크립트의 장점이나 좋은 개발자 경험의 원인, 에러를 줄이는 요소, 더 큰 생산성
자바스크립트는 매우 유연한 언어
다른 언어에서는 허용하지 않는 결과도 JS에서는 이상한 결과를 가져올지라도 코드가 실행된다.
예시) array 에 boolean 더하기
[1, 2, 3, 4] + false
//'1, 2, 3, 4false'
예시)
function divide (a, b) {
return a / b
}
라는 함수를 작성하고
divide("XXXXXX") 라는 이상한 값을 넣고 함수를 실행했을 때,
함수의 실행을 막는 대신
NaN 이 출력된다.
//입력값이 두개여야 하고, 숫자여야 하는데 막지 않았음
콘솔 안에서 발생하는 에러
코드가 실행 될 때 유저의 컴퓨터 안에서만 발생하는 에러일 수 있다.
예시)
const nico = { name: "nico" }
nico.hello()
//코드를 실행시키고 에러 발생
코드를 실행하기 전에 에러가 일어날 것을 미리 탐지할 수 있어야 한다.
C#, Java같은 강타입 언어
이러한 언어들은 작성 후 컴파일러를 통해 실행될 때 어셈블리어 같은 기계가 이해할 수 있는 언어로 변형된다.
타입스크립트의 경우에는 일반 자바스크립트로 변형된다.
브라우저가 타입스크립트가 아닌 자바스크립트를 이해하기 때문에
Node.js 는 둘 다 이해한다.
예시)
function divide (a, b) {
return a/ b
}
divide ("hello")
//에러메시지: Expected 2 arguments
a와 b의 타입을 정해야 하고
입력값의 개수를 맞춰야 한다.
데이터나 변수의 타입을 명시적으로 정의할 수도 있고, JS처럼 변수만 생성하고 넘어갈 수 있다.
타입스크립트는 이 경우 타입을 추론한다.
//묵시적으로 데이터의 타입을 추론하는 TS의 type checker
let a = "hello";
//let a: string
a = "bye"; //string -> string이므로 문제 없다.
a = 1
//Type '1' is not assignable to type 'string'.
//명시적으로 변수의 타입을 선언하는 문법
let b : boolean = "x";
// type 'string' is not assignable to type 'boolean'
//명시적 타입 선언이 꼭 필요한 경우
let c = [1, 2, 3]
//let c: number[]라고 타입체커가 추론한다.
c.push("1")
//Argument of type '"1"' is not assignable to parameter of type 'number'.
그러나 코드 작성 중 빈 배열을 일단 만들고 그 배열의 데이터타입을 정해줘야 할 경우에는
let c :number[] = []
로 작성해야 한다.
const player = {
name: "nico"
}
player.name = 1;
//type 'number' is not assignable to type 'string'
player.hello();
// Property 'hello' does not exist on type '{ name: string; }'
let a : number = 1;
let b : string[] = ['il'];
let c : boolean[] = [true];
const player = {
name: "nico"
}
//이런 object 가 여러개 있을 때, 모든 object 는 name을 가지고 있지만
//몇몇 object는 age 라는 필드를 추가로 가지고 있는 경우에는?
const player : {
name: string,
//이 필드는 선택적 변수라고 알려주는 기호: ?
age?: number,
} = {
name: "nico"
}
if (player.age < 10) {
//'player.age' is possibly undefined
console.log("age < 10");
}
//해당 필드의 값이 undifined 일 수 있다고 알려준다.
if (player.age && player.age < 10) {
console.log("age < 10");
}
//이런식으로 안전장치를 달아줘야 한다.
//같은 형식의 object를 여러개 만들어야 할 때
//그 object들의 타입을 일일히 정해주기 보다는
//alias를 미리 정해주는 것이 편하다.
//(C에서의 struct 선언과 비슷한 느낌)
type Player = {
//첫 글자는 대문자
name: string,
age?: number,
}
const nico : Player = {
name: "nico"
}
const lynn : Player = {
name: "lynn",
age:12
}
//이름만 받는 함수
function playerMaker(name:string) {
return {
name
//or name: name
}
}
const nico2 = playerMaker("nico");
nico2.age = 12;
//property 'age' does not exist on type '{name: string}'
//이 오류를 피하기 위해선 함수의 return 값의 타입을 정해야 한다.
function playerMaker(name:string) : Player {
return {
name
//or name: name
}
}
const nico2 = playerMaker("nico");
nico2.age = 12;
//화살표 함수의 경우는 다음과 같이 사용한다.
const playerMaker = (name:string) : Player => ({name});
type Player = {
readonly name: string
age?: number
}
const playerMaker = (name:string) : Player => ({name});
const nico = playerMaker("nico");
nico.age = 12;
nico.name = "las";
//cannot assign to 'name' because it is a read-only property.
한번 입력 값이 들어오면 수정하지 못하게 막는 속성
const numbers: readonly number[] = [1,2,3,4];
numbers.push(12);
//property 'push' does not exist on type 'readonly number[]'.
정해진 최소한의 길이와 특정 위치에 특정 타입이 있어야 하는 배열
//["nico", 12, false]와 같은 형태의 배열을 만들고 싶다
const player: [string, number, boolean] = ['nico', 12, false];
player[0] = 1;
//Type '1' is not assignable to type 'string'.
let a : undefined = undefined;
let b : null = null;
//선택적 타입을 사용할 때 해당 타입 또는 undefined 라는 형식으로 나타남
Typescript의 보호장치를 적용하고 싶지 않을 때 사용하는 타입
빈 배열 같은 경우는 자동적으로 any 타입이 된다.
const a : any[] = [1,2,3,4,5];
const b : any = true;
a + b;
작업을 실행하기 전 변수의 타입을 확인하게 하는 타입.
let a : unknown;
let b = a + 1;
//'a' is of type 'unknown'.
//이런식으로 a의 타입을 먼저 확인해야 함
if (typeof a === 'number') {
let b = a + 1;
}
if (typeof a === 'string') {
let b = a.toUpperCase();
}
아무것도 return 하지 않는 함수를 대상으로 사용
function hello() {
console.log ('hello');
}
//function hello() : void
const a = hello();
a.toUpperCase();
//property 'toUpperCase' does not exist on type 'void'
함수가 절대로 return 하지 않을 경우
또는 타입이 2가지 이상인 경우 해당 타입에 절대로 해당하지 않을 경우
function hello() : never {
throw new Error ("error");
}
function hello(name : string|number) {
if (typeof name === 'string'){
name // name : string
} else if (typeof name === 'number'){
name // name : number
} else {
name // name : never
}
}