const
, var
, let
등을 사용하여 변수를 선언할 때, 변수의 타입을 명시적으로 지정하기 위해 타입 표기를 추가할 수 있다.
=> typescript에서는 타입 추론이 가능하기 때문에 이는 선택 사항이다.
let myName = "Alice";
TypeScript에서는 함수의 입력 및 출력 타입을 지정할 수 있다.
함수를 선언할 때, 함수가 허용할 매개변수 타입을 선언하기 위해 각 매개변수 뒤에 타입을 표기할 수 있다. 매개변수 타입은 매개변수 이름 뒤에 표기한다.
function greet(name: string) {
console.log("Hello, " + name.toUpperCase() + "!!");
}
매개변수에 타입이 표기되었다면, 해당 함수에 대한 인자는 검사가 이루어진다.
greet(42);
Argument of type 'number' is not assignable to parameter of type 'string'.
반환 타입 또한 표기할 수 있다. 반환 타입은 매개변수 목록 뒤에 표기한다.
function getFavoriteNumber(): number {
return 26;
}
반환 타입은 표기하지 않아도 되는 것이 일반적이다.
왜냐하면 TypeScript가 해당 함수에 들어있는 return 문을 바탕으로 반환 타입을 추론할 것이기 때문이다.
const names = ["Alice", "Bob", "Eve"];
names.forEach((s) => {
console.log(s.toUppercase());
});
Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?
매개 변수 s 에는 타입이 표기되지 않았음에도 불구하고, TypeScript는 s 의 타입을 알아내기 위하여 배열의 추론된 타입과 더불어 forEach 함수의 타입을 활용하였다.
이 과정은 문맥적 타입 부여라고 불리는데, 왜냐하면 함수가 실행되는 문맥을 통하여 해당 함수가 가져야 하는 타입을 알 수 있기 때문이다.
이는 함수와 화살표 함수 둘 다 동일하게 실행된다.
객체 타입을 정의하려면, 해당 객체의 프로퍼티들과 각 프로퍼티의 타입들을 나열하기만 하면 된다.
function printCoord(pt: { x: number; y: number }) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });
프로퍼티를 구분할 때 ,
또는 ;
를 사용할 수 있고, 가장 마지막에 위치한 구분자의 표기는 선택 사항이다.
만약 타입을 지정하지 않는다면, 해당 프로퍼티는 any
타입으로 간주한다.
객체 타입은 일부 또는 모든 프로퍼티의 타입을 선택적인 타입, 즉 옵셔널
로 지정할 수 있다. 프로퍼티 이름 뒤에 ?를 붙이면 된다.
function printName(obj: { first: string; last?: string }) {
// ...
}
// 둘 다 OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });
옵셔널 프로퍼티를 읽었을 때, 해당 값을 사용하기에 앞서 undefined인지 여부를 확인해야 한다.
function printName(obj: { first: string; last?: string }) {
console.log(obj.last.toUpperCase())
};
Object is possibly 'undefined'.
function printName(obj: { first: string; last?: string }) {
if (obj.last !== undefined) {
console.log(obj.last.toUpperCase());
}
function printName(obj: { first: string; last?: string }) {
console.log(obj.last?.toUpperCase());
}
유니언 타입은 서로 다른 두 개 이상의 타입들을 사용하여 만드는 것으로, 유니언 타입의 값은 타입 조합에 사용된 타입 중 무엇이든 하나를 타입으로 가질 수 있습니다.
조합에 사용된 각 타입을 유니언 타입의 멤버라고 부릅니다.
function printId(id: number | string) {
console.log("Your ID is: " + id);
}
printId(101); // OK
printId("202"); // OK
printId({ myID: 22342 }); // OK
Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
TypeScript에서 유니언을 다룰 때는 해당 유니언 타입의 모든 멤버에 대하여 유효한 작업일 때에만 허용됩니다. 예를 들어 string | number
라는 유니언 타입의 경우, string
타입에만 유효한 메서드는 사용할 수 없습니다.
function printId(id: number | string) {
console.log(id.toUpperCase());
}
Property 'toUpperCase' does not exist on type 'string | number'.
Property 'toUpperCase' does not exist on type 'number'.
이를 해결하려면 코드상에서 유니언을 좁혀야 한다.
function printId(id: number | string) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
타입 별칭은 똑같은 타입을 한 번 이상 재사용 할 수 있게 하고, 다른 이름으로 부를 수 있다.
type Point = {
x: number;
y: number;
};
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });