https://www.typescriptlang.org/play
- 02.19 첫번째
- 03.05 두번째
- 03.12 세번째
- 정적 타입 검사 도구
- 자바스크립트 슈퍼셋
- 예) C++은 C의 슈퍼셋
- 기존의 언어를 꾸며줌
- 확장의 목적은 정적 타입 검사를 하기 위해
- MS에서는 타입스크립트를 "새로운 언어가 아니다"라고 말함
- "ECMAScript 문법을 따를 뿐 미래에 JS 문법이 될 것이다."라고 함.
- Lint를 잘쓰려면?
- Airbnb, ESLint 관련해서 룰을 잘 선언해야 함
- 정적 타입을 잘쓰려면?
- 타입 검사를 잘할 수 있게 타입을 잘 선언해야 함.
- 자바스크립트가 어떻게 동작하는지 타입을 선언하는 것.
- tsconfig
- 폴더마다 tsconfig을 만들수 있음
- extends 옵션으로 확장해서 사용할 수 있음
- files 옵션은 순서 결합도가 있음
- tsconfig 파일만으로 자바스크립트를 export 할 수 있다.
- input / output
- input: tsconfig의 reference, files
- output: tsconfig의 outFile 설정
- 주요 설계 목적
- 정적 구문 식별
- 상위 집합 언어
- 구조화 메커니즘 제공
- 제로 런타임 오버헤드
- 설계 시간(디자인-타임)과 실행 시간(컴파일-타임)으로 구분
- 디자인-타임: 작성한 코드를 의미
- 컴파일-타임: 타입스크립트를 자바스크립트로 변환
- ECMAScript 호환
- 크로스 플랫폼
- 타입스크립트 아키텍쳐
- tsserver(server.ts)
- Language Service(service.ts)
- 타입스크립트 동작 과정
- 타입 리졸버/체커
- 진단(Diagnostic)
- 타입 에러 발생 시, 문제있다고 보고해줌
- TS 파일 컴파일 완료 시
- JS 파일 내보냄
- d.ts: 제거되는 타입을 선언함
// 1.js
namespace ts {
function test() {
return 1
}
export function myFunc() {
return test()
}
}
// 2.js
namespace ts {
export function myFunc2() {
return myFunc()
}
}
"use strict";
// 1.js
var ts;
(function (ts) {
function test() {
return 1;
}
function myFunc() {
return test();
}
ts.myFunc = myFunc;
})(ts || (ts = {}));
// 2.js
(function (ts) {
function myFunc2() {
return ts.myFunc();
}
ts.myFunc2 = myFunc2;
})(ts || (ts = {}));
// v1.js
interface MyI {
age: number
name: string
}
// v2.js
interface MyI {
sex: string
}
Namespace에 Dot을 사용할 수 있다.
namespace ts {
export function myFunction() {
}
}
namespace ts.server {
export function myFunction() {
}
}
- Block scoped / reference
- 상수 효과를 볼 수 있다.
enum MyEnum {
MyEnum0 = 0,
MyEnum1 = 1,
MyEnum2 = 2,
}
const myEnum0 = MyEnum[0]
console.log(myEnum0) // 0
enum MyEnum2 {
MyEnum0 = '0',
MyEnum1 = '1',
MyEnum2 = '2',
}
console.log(Object.keys(MyEnum2)) // MyEnum0, MyEnum1, MyEnum2
const enum TokenFlags {
None = 0
}
console.log(TokenFlags.None) // 0
enum MyEnum2 {
MyEnum0 = 2,
MyEnum1 = 2,
MyEnum2 = MyEnum0 * MyEnum1,
}
console.log(MyEnum2.MyEnum2) // 4
- 특별한 힌트를 주지 않아도, 참조한 값을 알고 있는 것
type MyFunc = (first: number, second: string) => string
const myFunc: MyFunc = (first, second) => {
return second + first;
}
- 재사용성이 좋아짐. 생산성이 좋아짐
- 힌트를 효율적으로 줄 수 있음
interface Person<T> {
name: string;
age: number;
etc: T;
}
type PersonExtra = Person<string>
type PersonExtraNumber = Person<number>
interface Person<T, U = string> {
name: string;
age: number;
etc: T;
etc2: U;
}
type PersonExtra = Person<string>
type PersonExtraNumber = Person<number, number>
const FieldExtended = <
T extends BaseFieldExtend,
U extends
T['type'] extends 'string'
? string
: T['type'] extends 'date'
? Date
: T['type'] extends 'float'
? number
: never
> (baseField: T & { value: U }) => baseField;
FieldExtended({
type: 'date',
name: 'a',
value: new Date(),
});
declare namespace Immutable {
type DeepImmutable<T> =
T extends (infer R)[]
? DeepImmutableList<R>
: T extends object
? DeepImmutableMap<T>
: T;
interface DeepImmutableMap<T> {
get<K extends keyof T>(key: K): DeepImmutable<T[K]>
}
interface DeepImmutableList<T> {
get(idx: number): DeepImmutable<T>
}
function fromJS<T> (source: T): DeepImmutable<T>
function toJS<T> (obj: DeepImmutable<T>): T
}
const myState = [{a: {c: 1}}, 2];
const iList = Immutable.fromJS(myState);
const b = Immutable.toJS<typeof myState>(iList);
const myState = [{a: {c: 1}}, 2] as const;
const iList = Immutable.fromJS(myState);
const res = iList.get(1);
const b = Immutable.toJS<typeof myState>(iList);
오픈소스에서 기본 타입을 any로 했을 때 오버라이드를 한다.
declare module 'react-redux' {
export function useStore<
S = RootState,
A extends Action = AnyAction
> (): Store<S, A>
}
type UnwrapData<T> = T extends WrapperData<infer X> ? X : never;