근데 javascript로 typescript를 흉내낼 수 있다는데???
// @ts-check
/**
* @typedef {object} Address
* @property {string} street
* @property {string} city
*/
/**
* @typedef {object} User
* @property {string} name
* @property {string} email
* @property {Address} address
*/
function gretting (name: string): string {
return `${name}님 안녕하세요`
}
// 함수 타입 정의
interface APIFunc {
(url: string): Promise<Response>;
}
const LoginAPI: APIFunc = (url: string): Promise<Response> => {
return await fetch(url);
}
interface MyStringArray {
[index: number]: string; // index: value
}
interface MyDict {
[key: number]: RegExp; // key: value
}
// => 원하는 타입의 key, value를 가진 item만 삽입 가능.
interface Person {
id: number,
name: string
}
interface Developer extends Person {
language: string
}
const hyeon: Developer = { id: 4, name: '현정', language: 'js' };
// Developer 및 Person의 모든 속성 다 갖고 있어여함
type은 타입의 참조값을 갖는다. 새로운 타입을 만들어내는 interface와 다르다.
type으로는 타입을 확장하지 못한다. 그래서 type과 interface의 가장 큰 차이는 확장 가능 여부이다.
type MyType = string | number;
type MyType = string | number;
function myFunc (value: MyType) {
// 두 타입의 공통된 속성에 접근 가능 / 인터섹션 사용 시 합집합에 속하는 속성들에 접근 가능
if (typeof value === 'string') {
value. // string이 가진 속성 자동 완성
} else {
// number이 가진 속성 자동 완성
}
}
특정한 값의 집합을 사용할 때 사용 가능하다.
기본적으로 각 원소에는 실제 정수값이 0부터 할당된다.
명시적으로 숫자 또는 문자 값을 할당할 수 있다.
enum Answer {
YES = 'Y';
NO = 'N';
}
function check (answer: Answer) {
if (answer === Answer.YES) {
}
}
check(Answer.YES);
check(Answer.NO);
check('Yes'); // error!
js에서 사용할 수 있는 개념이기도 하나, 사용법이 약간 다르다.
java, c++ 등 다른 언어에서의 제네릭과 동일한 의미(사용하는 시점에 타입을 지정)를 가진다.
함수 또는 인터페이스 등에 제네릭을 활용할 수 있다.
function logText<T> (text: T): T {
console.log(text);
return text;
}
logText('제네릭을 사용하면 반환값의 타입에 대한 api가 자동완성돼요!');
그냥 제네릭을 사용하면 모든 타입들이 들어갈 수 있다. (string, number, Person...)
타입 제한을 적용해서 개선가능하다.
function printArray (array: T[]) {
array.length; // 기본적으로 배열에서 제공하는 api에 접근 가능
}
T extends [type] 사용 시, type의 속성을 가지고 있는 타입들만 사용하도록 제한할 수 있다.
그 밖의 타입의 값들 사용시 에러가 발생한다.