Intersection type
여러타입이 하나로 합쳐진 타입
interface User {
name: String;
}
interface Action {
do(): void;
}
function createUserAction(u: User, a: Action): User & Action { //&를 사용해서 인터섹션(교집합)타입을 만드는 방법
return { ...u, ...a};
}
const u = createUserAction({name: 'ony'}, { do() {} }); // 기존타입을 활용해서 위의 두타입을 같이 합쳐져야할떄 사용
Union type
| 를 사용해서 만드는 유니언(합집합)타입
function compare(x: string, y: string)
function compare(x: number, y: number)
function compare(x: string | number, y: string | number) { // ||를 사용해서 유니언(합집합)타입을 만드는 방법을 배움
// x. //x. 하면 string과 number 두가지타입에서 모두 사용가능한 매서드만 나온다
// 유니언 타입에서는 같은 타입끼리 비교하고 싶다면 타입가드 만들기
if(typeof x === typeof 'number' && typeof y === 'number'){
return x === y ? 0 : x> y ? 1 : -1;
// 두개가 같으면 0 아니면 x>y이면 1반환 아니면 -1반환
}
if(typeof x === typeof 'string' && typeof y === 'string'){
return x.localeCompare(y);
}
throw Error('not supported type');
}
const v1 = compare(1,2);
const v2 = compare("a","b");
// const v3 = compare("a",1); - 이렇게 하면 오류발생 위에 펑션 넣는 값을 적어줘서
console.log([3,2,1].sort(compare)) //소팅할때 컴페어 전달할 수 있음 - 앞에 안에 넣을 값을 숫자 넣어서 코드가 동작됨
console.log(['c','b','a'].sort(compare)) //소팅할떄 컴페어 전달할 수 있음 - 앞에 안에 넣을 값을 문자열 넣어서 코드가 동작됨
tsc
node dist/intersection-union.js
터미널에 위에 두줄을 입력하면 [1,2,3] 하고 ['a','b','c']가 출력됨
타입가드가 아닌 바로 type assertion을 처리해서 원하는 타입으로 고정하기
function isAction(v: User | Action) : v is Action {
return (<Action>v).do !== undefined; //Action>v가 do라는 속성이 있으면 얘는 액션이라고 본다
} //타입가드가 아니고 바로 type assertion을 처리해서 원하는 타입으로 고정해서 하단의 코드를 쓸수도 있음
function process(v: User | Action){ //매서드를 가져야하는 타입인데 인터페이스는 자바스크립트에 존재하지않음
//if (typeof v === "object") - 오브젝트 인지못해서 하면안된다
//if ((<Action>v).do) {//v가 Action이라고 생각하고 이 코드를 작성한다고 말해서 type assertion (<Action>v).do .do라는 매서드에 접근가능
//(<Action>v).do} // 이렇게 매번 해야하는데 이거를 안하려면
if(isAction(v)){
v.do();
} else {
console.log(v.name);
}
}
Index Type
속성의 이름이 정해져있지않고 동적으로 처리해야할때 사용
interface Props {
name: string;
[key: string]: string; //key: 의 값은 string과 number만 가능
}
const p: Props = {
name: 'hello',
a: 'd',
b: 'e',
c: '3',
// d: 3, //문자가 아니라서 오류남
0: 'ㅇ',
1: 'b'
}
p.name // 접근가능
p.dfsf // 인덱스 타입이라서 이떠한 뮨자열값도 접근이 된대 - 어떠한 키값이 나오는지 모를때 쓸 수 있다.?
p['a'] // 이렇게 키이름으로 접근가능
p[0] // 이렇게 숫자로도 접근가능 - 값은 'ㅇ'
keyof 연산자
유저의 특정타입의 키들(키의 이름이나 그것의 타입)에 접근함
let keys: keyof Props;
interface User3 {
name: string;
age: number;
hello(msg: string): void;
}
let keysOfUser: keyof User3; // 변수에 User3 의 키의 이름들(name, age,hello)이 유니언형태로 보이게 됨
keysOfUser ='age'
let helloMethod: User3["hello"]; // 이 변수는 User3의 "hello"타입만 할당할 수 있다
helloMethod = function(msg: string){ //스트링말고 넘버로 정의하면 오류남 헬로랑 타입이 같아야함
}
타입별칭
인터페이스와 비슷하지만 타입에 별칭을 지정할 수 있다
interface User {
name: String;
}
interface Action {
do(): void;
}
type UserAction = User & Action;
function createUserAction(): UserAction { // 리턴값이 UserAction
return {
do() {},
name: ''
}
}
//---
type UserState = "PENDING" | "APPROVED" | "REJECTED";
function checkUser(user: User2): UserState { //유저 검사 결과가 타입 유저상태로 나오게한다
if(user.login()) {
return "APPROVED";
} else {
return "REJECTED";
}
}
type StringOrNumber = string | number; // 원시형 타입도 사용가능
type Arr<T> = T[]; //제네릭도 타입별칭 사용가능 - T에 해당하는 배열의 타입별칭이 Arr
type P<T> = Promise<T>; // 프로미스(이전에 있던 타입)를 축약시켜서 이름(별칭)을 부여할수있음
type User2 = {
name: string;
login(): boolean;
}
class UserImpl implements User2 { //인터페이스가 아닌데도 implements가 가능함
login(): boolean {
throw new Error("Method not implemented.");
}
name: string;
}