Type System
ㄴ 컴파일러에게 사용하는 타입을 명시적으로 지정하는 시스템
ㄴ 컴파일러가 자동으로 타입을 추론하는 시스템
◽ Structural과 Nominal Type System
◾ Structural : 구조가 같으면 같은 타입 (TypeScript)
◾ Nominal : 구조가 같아도 이름이 다르면 다른 타입 (c언어,java)
◽ Type System of TypeScript
◾ 타입을 명시적으로 지정 가능
◾ 그렇지 않으면, typescript compiler가 자동으로 타입 추론
◽ Type
◾ 해당 변수가 할 수 있는 일을 결정
*duck typing
런타임에 발생하는 타이핑 방식 (파이썬)
If it walks like a duck and it quacks like a duck, then it must be a duck
옵션 ✔
nolmplicitAny 옵션
타입을 명시적으로 지정하지 않은 경우 typescript가 타입 추론 중 any라고 판단하게 되면 compile error 발생해 타입을 명시적으로 지정하도록 유도한다.
error!! Parameter '00' implicitly has an 'any' type.
sctrictNullChecks 옵션
모든 타입에 자동으로 포함되어 있는 null
과 undefined
를 제거해준다.
nolmplicitReturns 옵션
함수 내 모든 코드가 값을 리턴하지 않으면 complie error 발생
strictFunctiontypes 옵션
함수를 할당할 시 함수의 매개변수 타입이 같거나 슈퍼타입인 경우가 아니면 에러 발생 (변병)
타입 호환성 Type Compatibility
sub타입과 super타입
1 | number | |
number[] | object | |
[number, number] | number[] | |
number | any | <-> |
never | number | |
A extends B | A는 B에 상속 |
공변 📌
◽ primitive type : 같거나 sub타입이면 할당이 가능하다.
◽ object
, array
: 각각의 property가 대응하는 property와 같거나 sub타입이어야 한다.
let sub: string = '';
let sup: string | number = sub;
//
let sub: { a: string; b: number } = { a: '', b: 1};
let sup: { a: string | number; b: number } = sub;
//
let sub: Array<{ a: string; b: number }> = { a: '', b: 1};
let sup: Array<{ a: string | number; b: number }> = sub;
변병 📌
◽ 함수의 매개변수 타입만 같거나 super타입인 경우 할당이 가능하다.
class Person {}
class Developer extends Person {
coding() {}
}
class StartupDeveloper extends Developer {
burning() {}
}
function tellme(f: (d: Developer) => Developer) {}
// Developer => Developer 에다가 Developer => Developer 를 할당하는 경우
tellme(function dToD(d: Developer): Developer {
return new Developer();
});
// Developer => Developer 에다가 Person => Developer 를 할당하는 경우
tellme(function pToD(d: Person): Developer {
return new Developer();
});
// Developer => Developer 에다가 StartipDeveloper => Developer 를 할당하는 경우
tellme(function sToD(d: StartupDeveloper): Developer {
return new Developer();
});
타입 별칭 type alias
◽ interface랑 유사함
◽ primitive, union type, tuple, function
◽ 만들어진 타입의 refer(별명)로 사용, 타입을 만드는 개념이 아님
let person: string | number = 0;
person = 'Mark';
type StringOrNumber = string | number;
let another: StringOrNumber = 0;
another = 'Anna';
◽ 반복되어 사용될 때 유용
type EatType = (food: string) => void;
Type
1. Boolean
let isDone: boolean = false;
2. String
(큰 따옴표나 작은 따옴표)
let name: string = "Lenord";
2-1. Template String
행에 걸쳐 있거나 표현식을 넣을 수 있는 문자열은 백틱 기호를 사용한다. 그 안에 포함된 표현식은 ${expr}
와 같은 형태를 사용한다.
let fullName: string = "siot";
let sentence: string = ` hello
my name is ${fullName}.` // hello my name is siot.
3. Symbol
- ECMAScript2015에 추가
- new Symbol로 사용할 수 없다.
- Symbol을 함수로 사용해서 symbol타입을 만들어낼 수 있다. (함수는 대문자S, 타입은 소문자s)
console.log(Symbol('foo') === Symbol('foo'));
// 같은 함수, 같은 인자지만 결과는 다름
- primitive 타입의 값을 담아서 사용한다.
- 고유하고 수정불가능한 값으로 만들어준다.
- 접근을 제어하는데 주로 쓰인다.
const sym = Symbol(); // sym은 고유한 형태
const obj = {
[sym]: "value"
}
console.log(obj[sym]); // "value"
4. Null & undefined
- 그 자체로 유용하지 않고, 소문자만 존재한다.
number
(와 같은 다른 타입)에는null
또는undefined
를 할당 가능- --stricNullChecks 컴파일 옵션 사용 시
null
과undefined
는 자기 자식 혹은void
(undefined에 할당)만 할당 허용 - 이때,
null
과undefined
를 할당 가능하게 하려면 union type | 을 이용할 수 있다.
let v: void = undefined; // 타입인 동시에 값인 undefined, void는 값만 넣을 수 있고 자기 자신도 넣을 수 없다.
let union: string = null; // error!
let union: string | null = null; // null할당 가능
4-1. JavaScript에서의 null
null
이란 값으로 할당된 것이null
이다.null
이라는 타입은null
이라는 값만 가질 수 있다.- 무언가 있지만 사용할 준비가 덜 된 상태
- 런타임에서 typeof연산자를 사용할 경우 ->
object
let n: null = null; // null타입은 null
console.log(n); // 값 null
console.log(typeof n); // object
4-2. JavaScript에서의 undefined
- 값이 할당하지 않은 변수는 undefined라는 값을 가진다.
- object의 property가 할당되지 않았을 때도 undefined라는 값을 가진다.
- 무언가 아예 준비가 안 된 상태
- 런타임에서 typeof연산자를 사용할 경우 -> undefined
let u: undefiend = undefiend; // undefiend타입은 undefiend
console.log(u); // 값 undefiend
console.log(typeof u); // undefiend
5. Object
const person1 = { name: "siot", age: 99 };
내장 전역 객체 Object를 이용해 create메소드를 통해 객체 생성 -> 어떤 인자가 들어가야 할까
const person2 = Object.create({ name: "siot", age: 99 });
- primitive type이 아닌 것을 나타내고 싶을 때 사용하는 타입
- 다음과 같은 방식으로 type annotation하지 않는다.
let obj: object = {};
- 표현방법
obj = {name: 'siot'};
obj = [{name: 'siot'}];
- non-primitive type : error를 부르는 형식
obj = 99; //error
obj = 'siot'; //error
obj = true; //error //error
obj = 100n; //error, bigint 타입
obj = Symbole(); //error
obj = null; //error
obj = undefined; //error
declare function create(o: object | null): void;
create({prop: 0});
create(null);
create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error
object.create(0); // Error
6. Array
6-1. Javascript에서 array
는 객체다.
6-2. 표현방법 (공통의 타입으로 묶일 때)
ㄴ 선호되는 방식 number[]
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
6-3. 표현방법 (여러 타입으로 배열할 때)
let list: (number | string)[] = [1, 2, 3, "4"]
7. Tuple
- 순서와 타입, 길이도 일치해야 함
let x: [string, number];
x = ["hello", 99];
x[3] = "world"; // undefiend
const [first, second, third] = person;
8. Any
undefined
지만 타입에 구애받지않고 “어떤 것이든” 올 수 있음- 최대한 쓰지 않는게 안전하나 쓸 수밖에 없는 상황도 있음
- 컴파일 타임에 타입 체크가 정상적으로 이뤄지지 않으므로 지양
function returnAny(message): any {
console.log(message);
}
const any1 = returnAny("리턴");
*any
타입을 작성하지 않을 시 에러를 잡아주는 strict
의 옵션 nolmplicitAny
- 개체를 통해 전파된다.
let looselyTyped: any = {};
const d = looselyTyped.a.b.c;
9. Unknown
- 응용 프로그램을 작성할 때 모르는 변수의 타입을 묘사할 때
- 동적 콘텐츠, 사용자나 API의 모든 값을 의도적으로 수락하기를 원할 때
- 이 변수가 무엇이든 될 수 있음을 알려주는 타입을 제공할 때
any
보다 이후에 typescript 3.0버전부터 지원any
와 짝으로any
보다 type-safe한 타입any
와 같이 아무거나 할당할 수 있다.- 컴파일러가 타입을 추론할 수 있게 타입의 유형을 좁힌다.
- 타입을 확정해주지 않으면 다른 곳에 할당할 수 없고 사용할 수 없다.
- unknown타입을 사용하면 런타임 에러를 줄일 수 있다.
- 사용 전에 데이터의 일부 유형 검사를 수행해야 함을 알리는 API에 사용
declare const maybe: unknown;
const aNumber: number = maybe;
if (maybe === true) {
const aBoolean: boolean = maybe;
} // if문 안에서 한정되어 타입 가드
if (typeof maybe === 'string') {
const astring; string = maybe;
} // if문 안에서 한정되어 타입 가드
10. Never
- 모든 타입의 subtype으로 모든 타입에 할당 가능 하지만 어떤 것도 할당 할 수 없음
any
도never
에게 할당할 수 없음- Return에 사용되는 타입
function error(message: string): never {
throw new Error(message); // 리턴하지 않음
}
function fail() {
return error("failed");
}
function infiniteLoop(): never {
while(true) {}
}
- 모든 타입의 subtype이며 모든 타입에 할당 가능 반대로
never
에는 어떤 것도 할당 불가 any
도never
에 할당 불가- 잘못된 타입을 넣는 실수를 막고자 할 때 사용하기도 함
let a: string = "hello";
if (typeof a !== 'string') {
a; // never
}
declare cosnt a: string | number;
if (typeof a !== 'string') {
a; // number, typeof가드
}
11. void
- 어떤 타입을 가리키지 않는 빈 상태
- 변수에
void
를 지정하지 않고 값을 반환하지 않는undefined
를 반환하는 상태에 return타입으로 사용 - 아무것도 하지 않겠다는 것을 명시적으로 하는 타입
function returnVoid(message: string): void{
console.log(message);
return undefined;
}
'FE' 카테고리의 다른 글
Compilation context 컴파일 옵션, tsconfig 최상위 속성 top level properties (0) | 2021.11.21 |
---|---|
맥북 M1 zsh, brew, rbenv, gem, github 블로그까지 (0) | 2021.11.20 |
TypeScript 타입, Type Annotation 타입 지정 (0) | 2021.11.17 |
TypeScript 컴파일러 설치, nvm과 npm차이 (0) | 2021.11.16 |
정규표현식과 js메소드, 플래그, 패턴 (0) | 2021.11.15 |