JavaScript/TypeScript
TS 타입 시스템
IT Blue
2021. 6. 17. 00:25
타입 시스템
- 컴파일러에게 사용하는 타입을 명시적으로 지정하는 시스템
- 컴파일러가 자동으로 타입을 추론하는 시스템
TS의 타입 시스템
- 타입을 명시적으로 지정할 수 있다
- 타입을 명시적으로 지정하지 않으면, 타입스크립트 컴파일러가 자동으로 타입을 추론
noImplicitAny 옵션
- 해당 옵션을 사용하면 타입을 명시적으로 지정하지 않은 경우, 타입스크립트가 추론 중 'any' 라고
판단하게 되면, 컴파일 에러를 발생시켜 명시적으로 지정하도록 유도한다
strictNullChecks 옵션
- 해당 옵션을 사용하면 모든 타입에 자동으로 포함되어 있는 'null' 과 'undefined' 를 제거
nolmplicitReturns 옵션
- 해당 옵션을 사용하면 함수 내에서 모든 코드가 값을 리턴하지 않으면, 컴파일 에러를 발생
strictFunctionTypes 옵션
- 해당 옵션을 사용하면 함수를 할당할 시에 매개변수 타입이 같거나 슈퍼타입인 경우가 아닌 경우,
에러를 통해 경고
Structural Type System
- 구조가 같으면, 같은 타입이다 (TS 타입 체계)
interface IPerson {
name: string;
age: number;
speak(): string;
}
type PersonType = {
name: string;
age: number;
speak(): string;
};
let personInterface: IPerson = {} as any;
let personType: PersonType = {} as any;
personInterface = personType;
personType = personInterface;
Nominal Type System
- 구조가 같아도 이름이 다르면, 다른 타입이다 (대표적인 언어는 C언어, Java 등)
타입 호환성 (Type Compatibilty)
- 서브 타입
// sub1 타입은 sup1 타입의 서브 타입이다
let sub1: 1 = 1;
let sup1: number = sub1;
// sub1 = sup1; (에러)
// sub2 타입은 sup2 타입의 서브 타입이다
let sub2: number[] = [1];
let sup2: object = sub2;
// sub2 = sup2; (에러)
// sub3 타입은 sup3 타입의 서브 타입이다
let sub3: [number, number] = [1, 2];
let sup3: number[] = sub3;
// sub3 = sup3; (에러)
// sub4 타입은 sup4 타입의 서브 타입이다
let sub4: number = 1;
let sup4: any = sub4;
sub4 = sup4;
// sub5 타입은 sup5 타입의 서브 타입이다
let sub5: never = 0 as never;
let sup5: number = sub5;
// sub5 = sup5; (에러)
class Animal {}
class Dog extends Animal {
eat() {}
}
// sub6 타입은 sup6 타입의 서브 타입이다
let sub6: Dog = new Dog();
let sup6: Animal = sub6;
// sub6 = sup6; (에러)
// 1. 같거나 서브 타입인 경우, 할당이 가능하다 => 공변
// primitive type
let sub7: string = '';
let sup7: string | number = sub7;
// object - 각각의 프로퍼티가 대응하는 프로퍼티와 같거나 서브타입이어야 한다
let sub8: { a: string, b: number} = { a: '', b: 1 };
let sup8: { a: string | number; b: number } = sub8;
// array - object 와 마찬가지
let sub9: Array<{ a: string; b: number}> = [{ a: '', b:1 }];
let sup9: Array<{ a: string | number; b: number}> = sub9;
// 2. 함수의 매개변수 타입만 같거나 슈퍼타입인 경우, 할당이 가능하다 => 반병
class Person {}
class Developer extends Person {
coding() {}
}
class StartupDeveloper extends Developer {
burning() {}
}
function telme(f: (d: Developer) => Developer) {}
// Developer => Developer 에다가 Developer => Developer 를 할당하는 경우
telme(function dToD(d: Developer): Developer {
return new Developer();
});
// Developer => Developer 에다가 Person => Developer 를 할당하는 경우
telme(function pToD(d: Person): Developer {
return new Developer();
});
// Developer => Developer 에다가 StartupDeveloper => Developer 를 할당하는 경우
// 에러 발생
// telme(function sToD(d: StartupDeveloper): Developer {
// return new Developer();
// });
타입 별칭 (Type Alias)
- Interface 랑 비슷해보임
- Primitive, Union Tpye, Tuple, Function
- 기타 직접 작성해야하는 타입을 다른 이름을 지정할 수 있다
- 만들어진 타입의 refer(별명)로 사용하는 것이지 타입을 만드는 것은 아니다
// Aliasing Primitive
type MyStringType = string;
const str = 'world';
let myStr: MyStringType = 'hello';
myStr = str;
// Aliasing Union Type
let person: string | number = 0;
person = "Lee";
type StringOrNumber = string | number;
let another: StringOrNumber = 0;
another = 'Park';
// 유니온 타입은 A도 가능하고 B도 가능한 타입
// 길게 쓰는걸 짧게 사용
// Aliasing Tuple
let person: [string, number] = ['Lee', 25];
type PersonTuple = [string, number];
let another: PersonTuple = ['Park', 35];
// 튜플 타입에 별칭을 줘서 여러 곳에서 사용이 가능하다
// Aliasing Function
type EatType = (food: string) => void;