반응형
1. Intersection
2. Union Types
2. 타입 별칭 type-alias
3. 인덱스 타입
1. Intersection
- 여러 타입을 하나로 합쳐진 타입
interface User {
name: string;
}
interface Action {
do(): void;
}
//Intersection - 여러타입을 하나로 합쳐진 타입
function createUserAcion(u: User, a: Action): User & Action {
return { ...u, ...a };
}
const u = createUserAcion({ name: "jay" }, { do() {} });
u.do; //가능
u.name; //가능
2. Union Types
- or 을 사용해서 두 개의 타입 사용할 수 있게 한다.
1. Union Types - primitive 타입
//union type
//x에 string 또는 number 타입이 올 수 있다.
function compare(x: string | number, y: string | number) {
if (typeof x === "number" && typeof y === "number") { //타입가드
return x === y ? 0 : x > y ? 1 : -1;
}
if (typeof x === "string" && typeof y === "string") {
return x.localeCompare(y);
}
throw Error ("not supported type");
}
//함수의 오버로딩으로 같은 타입만 사용할 수 있게 해줌
function compare(x: string, y: string);
function compare(x: number, y: number);
function compare(x: string | number, y: string | number) {
if (typeof x === "number" && typeof y === "number") {
return x === y ? 0 : x > y ? 1 : -1;
}
if (typeof x === "string" && typeof y === "string") {
return x.localeCompare(y);
}
throw Error("not supported type");
}
const v = compare(1,"D") //error
const v = compare(1,1)
const v = compare("D","D")
2. Union Types - primitive 타입이 아닌 interface를 union 타입으로 했을 경우
- v는 두 union 타입의 공통된 멤버에만 접근할 수 있다.
2-1) 타입가드 없이 사용
interface User {
name: string;
}
interface Action {
do(): void;
}
function process(v: User | Action) {
//타입 확인시 typeof 연산자 사용시, 자바스크립트에서 제공되는 타입밖에 없어서 error 발생
if (typeof v === "object") {}
↓
//1. 바로 사용시,
if(v.do) //error
↓
//2.v의 타입을 Action으로 고정
//매번 이런식으로 타입을 정의하면 불편 -> 타입가드 만들기
if ((<Action>v).do) {
(<Action>v).do();
}
2-2) 타입가드 정의 후 사용
interface User {
name: string;
}
interface Action {
do(): void;
}
//타입가드
function isAction(v: User | Action): v is Action {
//타입가드 정의
return (<Action>v).do !== undefined;
}
function process(v: User | Action) {
if (isAction(v)) {
//타입가드로 v는 Action타입으로 인식
v.do();
} else {
//알아서 User타입으로 인식
v.name;
}
}
3. 타입 별칭
- 인터페이스와 비슷하지만, 직접 작성한 타입에 이름을 붙일 수 있다.
- type 키워드를 통해 작성
1. intersection 타입으로, union 타입으로, 제네릭으로
//1) intersection 타입으로 우선 정의
type UserAction = User & Action;
function createUserAction(): UserAction {
//intersection 타입 반환 가능
return {
name: "",
do() {},
};
}
//2) 원시형 타입도 가능, union 타입
type StringOrNumber = string | number;
//3) 타입 별칭은 제네릭도 사용가능
type Arr<T> = T[];
//+ promise 축약해서 간단하게도 가능
type P<T> = Promise<T>;
2. interface처럼 특정 타입을 정의할 수 있다.
- implements도 가능
//4) 인터페이스처럼 특정 타입을 정의할 수 도 있다.
type User22 = {
name: string;
login(): boolean;
};
// ↓ 인터페이스가 아닌데 implement도 가능하다
class User333 implements User22 {
login(): boolean {
throw new Error("Method not implemented.");
}
name: string;
}
3. 문자 리터럴 타입과 같이 활용 시 유용
- ex) 상태에 따른 타입
//5) 문자 리터럴 타입과 같이 활용시 유용하다.
type UserState = "PENDING" | "APPROVED" | "REJECTED"; //union으로 묶어서 상태에 따른 타입
function chechUser(user: User22): UserState {
if(user.login()){
return "APPROVED";
}else{
return "REJECTED"
}
4. 인덱스 타입
- 속성의 이름이 정해져있지않고 동적으로 처리해야 할 때 사용
interface Props {
[key: string]: string; //인덱스 시그니처 매개변수는 string, number 만 사용가능
}
const p: Props = {
a: "d",
b: "e",
c: 3, //error
3: "a", //key가 string인 경우, number가 key값이어도 가능, but, key가 number인 경우 string은 불가
};
//+) 특정 속성을 고정하고 싶은 경우
interface Propss {
name: string;
[key: string]: string;
}
const pp: Propss = {
name: "hello",
a: "d",
b: "e",
};
- key가 string인 경우, number가 key값이어도 가능 but, key가 number인 경우 string은 불가
2. `keyof` 연산자로 key들에 대한 type을 가져올 수 있다.
let keys: keyof Propss;
//결과 => let keys: string | number - key가 string인 경우 number 값도 가능하기 떄문
//+ 인덱스 타입이 아닌 인터페이스에 keyof 연산자 사용하면?
interface User {
name: string;
age: number;
hello(msg: string): void;
}
let keyOfUser: keyof User;
// 결과 => let keyOfUser : "hello" | "name" | "age" 각 key를 union 타입으로 가져온다
'TypeScript' 카테고리의 다른 글
React + Typescript (0) | 2021.01.28 |
---|---|
[TypeScript 강의노트] - generic (0) | 2021.01.21 |
[TypeScript 강의노트] - class (0) | 2021.01.21 |
[TypeScript 강의노트] (0) | 2021.01.21 |