TypeScript types

μ°Έκ³ 

ν•™μŠ΅ λͺ©ν‘œ

  • TypeScriptμ—μ„œ μ΄μš©ν•  수 μžˆλŠ” νƒ€μž…μ„ μ‚΄νŽ΄λ³΄κ³ , νƒ€μž…μœΌλ‘œ 무엇을 ν•  수 μžˆλŠ”μ§€ μ•Œμ•„λ³Έλ‹€.

νƒ€μž…(type)μ΄λž€?

κ°’κ³Ό 이 κ°’μœΌλ‘œ ν•  수 μžˆλŠ” 일의 μ§‘ν•©

νƒ€μž…μ€ νƒ€μž…κ²€μ‚¬κΈ°(typechecker)λ₯Ό 톡해 μœ νš¨ν•˜μ§€ μ•Šμ€ λ™μž‘μ΄ μ‹€ν–‰λ˜λŠ” 일을 μ˜ˆλ°©ν•œλ‹€.

νƒ€μž… ν™•μΈμžλŠ” νŠΉμ • λ™μž‘μ΄ μœ νš¨ν•œμ§€ μ•„λ‹Œμ§€ νŒλ‹¨ν•  수 μžˆλ‹€.

TypeScript νƒ€μž… 계측

좜처: https://www.oreilly.com/library/view/programming-typescript/9781492037644/ch03.html TypeScript νƒ€μž… 계측

νƒ€μž…μ„ μ΄μ•ΌκΈ°ν•˜λ‹€

function squareOf(n) {
	return n * n
}
squareOf(2) //4둜 평가
squareOf('z') //NaN둜 평가

squareOf ν•¨μˆ˜λŠ” 숫자λ₯Ό νŒŒλΌλ―Έν„°λ‘œ λ°›μœΌλ©°, *ν‚€μ›Œλ“œλ₯Ό 톡해 κ³±μ…ˆμ˜ 숫자λ₯Ό λ°˜ν™˜ν•˜λŠ”κ±Έ

μ½”λ“œμƒμœΌλ‘œ 예츑 ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ λ§€κ°œλ³€μˆ˜μ— λ¬Έμžμ—΄ νƒ€μž…μ„ μ „λ‹¬ν•˜λ©΄ μ˜λ„μ™€ λ‹€λ₯Έ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œλ‹€.

function squareOf(n: number) {
	return n * n
}
squareOf(2) //4둜 평가
squareOf('z') //μ—λŸ¬ TS2345: 'z' λΌλŠ” νƒ€μž…μ˜ μΈμˆ˜λŠ” 'number' νƒ€μž…μ˜ λ§€κ°œλ³€μˆ˜μ— ν• λ‹Ήν•  수 μ—†μŒ

TypeScriptμ—μ„œλŠ” μˆ«μžκ°€ μ•„λ‹Œ λ‹€λ₯Έ νƒ€μž…μ„ 인수둜 μ „λ‹¬ν•˜λ©΄ μ—λŸ¬λ₯Ό λ°œμƒ μ‹œν‚¨λ‹€.

  • squareOf의 λ§€κ°œλ³€μˆ˜ n은 number둜 μ œν•œλœλ‹€.
  • 2λŠ” number에 ν• λ‹Ή κ°€λŠ₯ν•œ β€˜νƒ€μž…β€™μ˜ 값이닀.

TypeScriptμ—μ„œλŠ” νƒ€μž… μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 νƒ€μž…μ˜ μ œν•œμ„ λ‘˜ 수 있고, 호좜 및 할당을 μ œν•œ ν•  수 μžˆλ‹€.

β€˜TypeScriptλŠ” νŠΉμ • νƒ€μž…μ΄ 와야 ν• λ•Œ 이λ₯Ό λͺ…μ‹œν•  수 μžˆλŠ” 언어’ 라고 이해할 수 μžˆλ‹€.’

νƒ€μž…μ˜ κ°€λ‚˜λ‹€

νƒ€μž…μ˜ μ’…λ₯˜μ™€ νƒ€μž… 별칭, μœ λ‹ˆμ˜¨(ν•©μ§‘ν•©) νƒ€μž…, μΈν„°μ„Ήμ…˜(ꡐ집합) νƒ€μž… 등을 μ•Œμ•„λ³Έλ‹€.

λΆˆλ¦¬μ–Έ Boolean

μ°Έ(true) / κ±°μ§“(false) 값을 λ‚˜νƒ€λ‚Έλ‹€.

let isBool: boolean;
let isLoading: boolean = false;

숫자 Number

λͺ¨λ“  λΆ€λ™μ†Œμˆ˜μ  값을 λ‚˜νƒ€λ‚΄κ³ ,

ECMAScript 2015에 μ†Œκ°œλœ 2μ§„μˆ˜, 8μ§„μˆ˜ λ¦¬ν„°λŸ΄λ„ μ§€μ›ν•œλ‹€.

let num: number;
let integer: number = 1;
let float: number = 3.14;
let hex: number = 0xf00d; // 61453
let binary: number = 0b1010; // 10
let octal: number = 0o744; // 484
let infinity: number = Infinity;
let nan: number = NaN;
let a: 26.218 = 26.218;
let b: a = 21 //μ—λŸ¬ TS2322: '21'νƒ€μž…μ„ '26.218'에 ν• λ‹Ήν•  수 μ—†μŒ
let oneMillion = 1_000_000 // 1000000 κ³Ό κ°™μŒ
let twoMillion: 2_000_000 = 2_000_000

λ¬Έμžμ—΄ String

λ¬Έμžμ—΄μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

μž‘μ€ λ”°μ˜΄ν‘œ ' , ν°λ”°μ˜΄ν‘œ " κ³Ό ES6 ν…œν”Œλ¦Ώ λ¬Έμžμ—΄λ„ μ§€μ›ν•œλ‹€.

let str: string;
let car: string = 'bmw';
let bicycle: string = 'citi100';
let brandCar: string = `${car} is brand car`;
let transport: string = 'My transport is' + bicycle;
let a: 'john' = 'john';
let b: 'john' = 'bob'; //μ—λŸ¬ TS2322: 'bob' νƒ€μž…μ„ 'john' νƒ€μž…μ— ν• λ‹Ή ν•  수 μ—†μŒ

λ°°μ—΄ Array

λ°°μ—΄ νƒ€μž…μ€ λ‚˜νƒ€λ‚΄λŠ” νƒ€μž… 뒀에 [] 을 μ“°κ±°λ‚˜, μ œλ„€λ¦­ λ°°μ—΄νƒ€μž… Array<elemType>둜 μ“Έ 수 μžˆλ‹€.

let student: string[] = ['bob', 'john'];
//let student: Array<string> = ['bob', 'john'];
let unionTypeArr: (string | number)[] = ['a', 1 , 'b', 2, 3];

// interface type
interface Student {
	name: string,
	age: number
}

const students : Student[] = [
	{name:'john', age:20},
	{name:'bob', age:21}
]

// readonly type
let nums: readonly number[] = [1,2,3];
nums[0] = 0; // Error - TS2542: Index signature in type 'readonly number[]' only permits reading.
nums.push(4); // Error - TS2339: Property 'push' does not exist on type 'readonly number[]'.

νŠœν”Œ Tuple

νƒ€μž…μœΌλ‘œ κ³ μ •λœ 길이λ₯Ό κ°€μ§„ 배열을 ν‘œν˜„ν•œλ‹€.

But, push , splice array prototype λ©”μ†Œλ“œλŠ” 막을 수 μ—†λ‹€..이 무슨?!

let tuple: [boolean, number];
tuple = [true, 1];
tuple = [false, 1, 2]; // error
tuple = [1, false]; // error

let car: [number, string, boolean] = [300, 'bmw', true];
console.log(car[0]); // 300
console.log(car[1]); // 'bmw'
console.log(car[2]); // true

let car: [number, string, boolean][];
car = [[300, 'bmw', true], [100, 'hyundai', true], [200, 'kia', true]];

let student: [string, number];
student = ['bob', 20];
student.push('john');
console.log(student) // ['bob', 20, 'john']
student.push({name:'k', age: 21}); // Error - TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'

μ—΄κ±°ν˜• Enum

값을 ν• λ‹Ήν•˜μ§€ μ•ŠμœΌλ©΄ 0 λΆ€ν„° μ‹œμž‘ν•œλ‹€.

μ—­λ°©ν–₯ 맀핑도 μ§€μ›ν•œλ‹€. (단, const enum μ•„λ‹λ•Œλ§Œ κ°€λŠ₯함.)

enum Language {
	English,
	Spanish,
	Russian
}

console.log(Language[0]) // English
console.log(Language.English) // 0
console.log(Language.Spanish) // 1

enum Language {
	English = 10,
	Spanish = 200 + 300,
	Russian
}

console.log(Language[0]) // English
console.log(Language.English) // 10
console.log(Language.Russian) // 501

const enum Language {
	English = 10,
	Spanish = 200 + 300,
	Russian
}

console.log(Language[0]) // error const enum은 λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄λ‘œλ§Œ μ ‘κ·Όν•  수 있음
console.log(Language.English) // 10
console.log(Language.Russian) // 501

λͺ¨λ“  νƒ€μž… Any

μ–΄λ–€ νƒ€μž…μ˜ 값도 ν• λ‹Ή ν•  수 μžˆλ‹€.

μ΅œλŒ€ν•œ μ§€μ–‘ν•˜λŠ”κ±Έ μΆ”μ²œ.

μ™ΈλΆ€ 라이브러리 μ‚¬μš©μ‹œ @types κ°€ μ—†λŠ” 경우 μ‚¬μš©ν•  수 μžˆλ‹€.

μ§„μ§œ λ§κ·ΈλŒ€λ‘œ λ‹€ ν• λ‹Ή ν•  수 μžˆμ–΄μ„œ μ˜ˆμ‹œλŠ” λ„˜μ–΄κ°„λ‹€.

μ•Œ 수 μ—†λŠ” νƒ€μž… Unknown

μ΅œμƒμœ„ νƒ€μž…μΈ unknown 은 μ–΄λ–€ νƒ€μž…μ˜ 값도 ν• λ‹Ή ν•  수 μžˆμ§€λ§Œ,

unknown 을 λ‹€λ₯Έ νƒ€μž…μ—λŠ” ν• λ‹Ή ν•  수 μ—†λ‹€.

let a: any = 'abc';
let u: unknown = 123;

let can: boolean = a; // 성곡 anyλŠ” 만λŠ₯.
let cant: number = u; // μ‹€νŒ¨ unknown은 anyλ₯Ό μ œμ™Έν•œ λ‹€λ₯Έ νƒ€μž…μ— ν• λ‹Ήν•  수 μ—†λ‹€.
let can2: any = u; // 성곡
let can3: number = u as number; // νƒ€μž…λ‹¨μ–Έμ‹œμ— κ°€λŠ₯

let a: unknown = 55
let b = a === 123 // false => bλŠ” boolean νƒ€μž…μ΄ 됨.

객체 Object

typeof μ—°μ‚°μžκ°€ object 둜 λ°˜ν™˜ν•˜λŠ” νƒ€μž….

tsconfig μ—μ„œ string : true 이면 null 은 objectκ°€ μ•„λ‹˜ (null 아웃)

사싀 거의 λͺ¨λ“  μƒμœ„ νƒ€μž…μ΄λΌ λΉ„μΆ”μ²œ.

객체라면 속성듀에 λŒ€ν•΄ μΈν„°νŽ˜μ΄μŠ€λ‚˜ νƒ€μž… 생성을 μΆ”μ²œ.

//λΉ„μΆ”
let obj: object = {};
let arr: object = [];
let func: object = function () {};
let date: object = new Date();

//μΆ”μ²œ
interface IStudent {
	name: string,
	age: number
}

let student: { name: string, age: number } = {
  name: 'bob',
  age: 20
};

let student: IStudent = {
  name: 'bob',
  age: 20
};

큰 μ •μˆ˜ Bingint

numberλŠ” 253κΉŒμ§€ μ •μˆ˜λ₯Ό ν‘œν˜„ν•˜μ§€λ§Œ, bigint λŠ” 더 큰 μˆ˜λ„ ν‘œν˜„ κ°€λŠ₯.

BigIntλŠ” μ •μˆ˜ λ¦¬ν„°λŸ΄μ˜ 뒀에 n을 λΆ™μ΄κ±°λ‚˜(10n) ν•¨μˆ˜ BigInt()λ₯Ό ν˜ΈμΆœν•΄ 생성할 수 μžˆλ‹€.

let a = 2134n //bigint
const b = 5785n //5785n
let e = 77.5n //μ—λŸ¬ μ •μˆ˜μ—¬μ•ΌλŒ
let f: bigint = 100n //bigint

null, undefined

null, undefined λŠ” λͺ¨λ“  νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž…μ΄λ‹€.

let a = string = null;
let b = string = undefined;
let obj = {a:1} = undefined;
let obj = {a:1} = null;
let v = void = null;
let v = void = undefined;

void

λ°˜ν™˜ ν•  값이 μ—†λŠ” ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•œλ‹€.

function helloworld(name: string): void {
	console.log(`hello world ${name}`);
}
const hi: void = helloworld('bob');
console.log(hi); // undefined

never

μ ˆλŒ€ λ°œμƒν•  수 μ—†λŠ” νƒ€μž….

μ ˆλŒ€ λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” νƒ€μž….

νƒ€μž… κ°€λ“œμ— μ˜ν•΄ 아무 νƒ€μž…λ„ μ–»μ§€ λͺ»ν•˜κ²Œ μ’ν˜€μ§€λ©΄ never νƒ€μž…μ„ μ–»κ²Œλ¨.

unknown κ³Ό λ‹€λ₯΄κ²Œ any 쑰차도 ν• λ‹Ή ν•  수 μ—†λŠ” νƒ€μž…. 였직 본인만 λ³ΈμΈμ—κ²Œ ν• λ‹Ή κ°€λŠ₯.

function errorFunc() {
    return error("Something wrong!"); 
}

function errorFunc(message: string): never {
    throw new Error(message);
}

ν•¨μˆ˜ function

ν™”μ‚΄ν‘œ ν•¨μˆ˜ ν†΅ν•΄μ„œ νƒ€μž… 지정이 κ°€λŠ₯ν•˜λ‹€.

μΈμˆ˜μ™€ λ°˜ν™˜ κ°’μ˜ νƒ€μž…μ„ μ§€μ •ν•  수 μžˆλ‹€.

let func: (arg1: number, arg2: number) => number;
func = function (x:number, y:number): number {
  return x + y;
};

let func: () => void;
func = function () {
  console.log('Hi bob');
};

νƒ€μž… 별칭

λ³„μΉ­μ΄λž€ λ³€μˆ˜λ₯Ό μ„ μ–Έν•΄μ„œ κ°’ λŒ€μ‹  λ³€μˆ˜λ‘œ μΉ­ν•˜λ“―μ΄ β€˜νƒ€μž… 별칭’ 으둜 νƒ€μž…μ„ 가리킬 수 μžˆλ‹€.

TypeScriptλŠ” 별칭을 μΆ”λ‘ ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ λ°˜λ“œμ‹œ λ³„μΉ­μ˜ νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•΄μ•Ό ν•œλ‹€.

type Age = number
type Person = {
	name: string
	age: Age
}

let age: Age = 20
let driver: Person = {
	name:'bob',
	age: age
}

// AgeλŠ” number의 λ³„μΉ­μ΄λ―€λ‘œ number에도 ν• λ‹Ήν•  수 μžˆλ‹€.
let age = 20
let driver: Person = {
	name:'bob',
	age: age
}

μœ λ‹ˆμ˜¨(union)

Or 쑰건이라고 μƒκ°ν•˜λ©΄ λœλ‹€.

2개 μ΄μƒμ˜ νƒ€μž…μ„ ν—ˆμš©ν•˜λŠ” 경우, | ν‚€μ›Œλ“œλ₯Ό 톡해 κ΅¬λΆ„ν•˜κ³ , () λŠ” 선택사항.

let union: string | number;
let unionOptional: (string | number);
union = 'Union type';
union = 123;
union = false; // Error - TS2322: Type 'false' is not assignable to type 'string | number'.

μΈν„°μ„Ήμ…˜(Intersection)

μœ λ‹ˆμ˜¨κ³Ό λ°˜λŒ€. And 쑰건이라고 μƒκ°ν•˜λ©΄ λœλ‹€.

2개 μ΄μƒμ˜ νƒ€μž…μ„ μ‘°ν•©ν•˜λŠ” 경우, & ν‚€μ›Œλ“œλ₯Ό 톡해 μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.

interface IStudent {
  name: string,
  age: number
}

interface IOff {
  isOff: boolean
}

const who: IStudent & IOff = {
  name: 'bob',
  age: 20,
  isOff: true
};

μ„ νƒν˜• ν”„λ‘œνΌν‹° 및 인덱슀 μ‹œκ·Έλ‹ˆμ²˜

μˆ˜λ§Žμ€ 속성을 κ°€μ§€κ±°λ‚˜ 단언할 수 μ—†λŠ” μž„μ˜μ˜ 속성이 ν¬ν•¨λ˜λŠ” κ΅¬μ‘°μ—μ„œ μ‚¬μš©κ°€λŠ₯ν•œ 인덱슀 μ‹œκ·Έλ‹ˆμ²˜.

인덱싱에 μ‚¬μš©ν•  μΈλ±μ„œ(Indexer)의 이름과 νƒ€μž… 그리고 인덱싱 결과의 λ°˜ν™˜ κ°’ νƒ€μž…μ„μ„ μ§€μ •ν•œλ‹€.

μΈλ±μ„œμ˜ νƒ€μž…μ€ stringκ³Ό number만 μ§€μ •ν•  수 μžˆλ‹€.

let a : {
	b: number,
	c?: string,
	[key:number]: boolean | string | number[]
}

interface IAlphabet {
  [alphabetIndex: number]: string
}
let alphatbet: IAlphabet = ['a', 'b', 'c']; // Indexable type
console.log(alphatbet[0]); // 'a' is string.
console.log(alphatbet[1]); // 'b' is string.
console.log(alphatbet['0']); // Error - TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

juunone
Written by@juunone
야크 쉐이빙을 ν•˜λ©° 더 쒋은 μ½”λ“œλ₯Ό μ„€κ³„ν•˜κ³  μƒκ°ν•©λ‹ˆλ‹€.

GitHubLinkedIn