typescript
는 선언한 함수의 인자가 any
인 것을 선호하지 않는다.const add = (a, b) => a + b;
// Parameter 'a' implicitly has an 'any' type.
// Parameter 'b' implicitly has an 'any' type.
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
type Config = {
path: string;
state: object;
};
type Push = {
(path: string): void;
(config: Config): void;
};
const push: Push = (config) => {
if (typeof config === "string") {
console.log(config);
} else {
console.log(config.path, config.state);
}
};
Push
의 config
에 Config
가 overload되었다.
push()
의 인자는 두 가지 타입을 가진다.
config
는 string
이다.config
가 string
이 아닐 때 Config
타입을 갖게 되어, config.path
와 config.state
를 호출할 수 있다.타입이 같고 개수가 다른 Call Signatures를 가지고 있다면, 함수 내 나머지 인자도 타입을 지정해야 한다.
type Add = {
(a: number, b: number): number;
(a: number, b: number, c: number): number;
};
// Type '(a: number, b: number, c: number) => number' is not assignable to type 'Add'.
const add: Add = (a, b, c) => {
// 'c' is declared but its value is never read.
return a + b;
};
c
는 옵션이기 때문에 타입을 옵셔널로 지정한다.type Add = {
(a: number, b: number): number;
(a: number, b: number, c: number): number;
};
const add: Add = (a, b, c?: number) => {
if (c) return a + b + c;
return a + b;
};
type SuperPrint = {
(arr: number[]): void;
(arr: boolean[]): void;
};
const superPrint: SuperPrint = (arr) => {
arr.forEach((i) => console.log(i));
};
superPrint([1, 2, 3, 4]);
superPrint([true, false, true]);
superPrint(["a", "b", "c"]);
// Overload 2 of 2, '(arr: boolean[]): void', gave the following error.
// Type 'string' is not assignable to type 'boolean'.
superPrint([1, 2, true, false, "a"]);
// Overload 2 of 2, '(arr: boolean[]): void', gave the following error.
// Type 'string' is not assignable to type 'boolean'.
typescript
의 Generic
을 사용한다.type SuperPrint = {
<TypePlaceholder>(arr: TypePlaceholder[]): void;
};
const superPrint: SuperPrint = (arr) => {
arr.forEach((i) => console.log(i));
};
superPrint([1, 2, 3, 4]);
// superPrint: <number>(arr: number[]) => void
superPrint([true, false, true]);
// const superPrint: <boolean>(arr: boolean[]) => void
superPrint(["a", "b", "c"]);
// const superPrint: <boolean>(arr: boolean[]) => void
superPrint([1, 2, true, false, "a"]);
// const superPrint: <string | number | boolean>(arr: (string | number | boolean)[]) => void
Generic
은 단일 타입이 아닌 다양한 타입에서 작동하도록 하는, 개발자가 요구한 대로 signature를 생성해주는 도구이다.Gneric
이 처음 사용되는 지점을 기반으로 해당 타입을 알아낸다.any
처럼 하나의 타입에 얽매이지 않지만, 타입 정보를 잃지 않는다.// any
type SuperPrint = {
(arr: any[]): any;
};
const superPrint: SuperPrint = (arr) => arr[0];
const a = superPrint([1, 2, 3, 4]);
const b = superPrint([true, false, true]);
const c = superPrint(["a", "b", "c"]);
const d = superPrint([1, 2, true, false, "a"]);
a.toUpperCase(); // No Error
// Generic
type SuperPrint = {
<T>(arr: T[]): T;
};
const superPrint: SuperPrint = (arr) => arr[0];
const a = superPrint([1, 2, 3, 4]);
const b = superPrint([true, false, true]);
const c = superPrint(["a", "b", "c"]);
const d = superPrint([1, 2, true, false, "a"]);
a.toUpperCase(); // Property 'toUpperCase' does not exist on type 'number'.
type
을 선언하지 않고 만들 수 있다.function superPrint<V>(a: V[]) {
return a[0];
}
Generic
사용도 가능하다.type Player<E> = {
name: string;
extraInfo: E;
};
type JsExtra = {
favFood: string;
};
type JsPlayer = Player<JsExtra>;
const js: JsPlayer = {
name: "js",
extraInfo: {
favFood: "pork",
},
};
const ts: Player<null> = {
name: "ts",
extraInfo: null,
};
Generic
을 사용할 수 있다.type A = Array<number>;
let a: A = [1, 2, 3, 4];