타입스크립트?
타입스크립트의 구성 4가지
- 프로그래밍 언어: 새로운 구문이 포함된 언어
- 타입 검사기(TypeChecker): 코드의 모든 구성요소(함수,변수 등)를 이해하고 오류 감별
- 컴파일러(Pre-Compiler): TS Syntax-tree를 JS Code로 생성 (cf. AltJS)
- Pre 는 선처리가 된다는 말
- 언어지원 서비스(IDE): VSCode, SublimeText, Vim 등의 편집기에서 TS 지원
타입스크립트 연습하는 사이트
https://www.typescriptlang.org/play/
Settings의 AST를 check하고, 버전을 v5.1.6으로 하여 AST를 확인하자
타입스크립트는
전역의 i와 함수의 i는 서로 다른 심볼로 같은 변수라도 스코프에 따라서 에러가 날 수도 있고 안날 수도 있다.
타입스크립트 설치하기
$> mkdir ts && cd ts
$> npm init -y
$> npm install -g typescript ts-node
$> tsc -v
$> tsc --init
$> cat tsconfig.json
$> ts-node hello.ts
- ts파일을 만들고 git bash에 tsc 입력하면 js파일이 생김
- 그리고 tsc –watch를 git bash에 입력해두면 ts파일을 수정하면 자동으로 js파일도 바뀜
타입스크립트의 타입
//null
let value: null = null;
//undefined
let value: undefined = undefined;
//boolean
let isDone: boolean = false;
//string
let name: string = "TypeScript";
let greeting: string = `Hello, ${name}`;
//큰따옴표("), 작은따옴표('), 또는 백틱(`)을 사용하여 문자열을 정의할 수 있습니다
//number
let count: number = 10;
let pi: number = 3.14159;
//bigint
let largeNumber: bigint = 123456789012345678901234567890n;
//symbol
let sym1 = Symbol("description");
let sym2 = Symbol("description"); // 서로 다른 Symbol 값
//고유하고 변경 불가능한 값으로, 객체의 속성 키로 사용할 수 있습니다.
타입설정하기
let x: number;
x=10;
console.log("🚀 x:", x);
x='abc';
console.log("🚀 x:", x);
로 하면 x는 number로 되어있기에 abc에서 오류뜸
-
따라서 let x: number sring;으로 해줌 > 유니언(union, (파이프)): 값에 허용되는 타입을 두 개 이상의 가능한 타입으로 확장하는 것
초기값이 없는 변수
타입 undefined로 주자 (any로 주지 말자)
-
할당 되기 전, 속성 중 하나에 접근 하려고 하는 것처럼 변수를 사용하려고 하면 에러 발생
-
undefined 유니온 타입일 때 접근 가능한 이유는 undefined 할당 가능성을 미리 알렸기 때문 - JS에서는 값을 할당하지 않는다면 초기화 값인 undefined를 참조, TS에선 이를 미리 타입으로 설정해야 참조 가능
=> 결론: undefined 가능성을 미리 알리지 않았기 때문에 할당 없이 접근하려고 했을 때 에러 발생
type 정의
- 타입스크립트에서 type 키워드를 사용하여 객체의 타입을 정의하는 방법은 매우 유용합니다. 이를 통해 객체 구조를 미리 정의하고, 해당 구조를 여러 곳에서 재사용할 수 있습니다. type 키워드를 사용하여 특정 타입의 형식을 정의할 수 있으며, 인터페이스와 유사하게 동작합니다.
type User = {
id:number;
name:string;
age:number;
address:string;
}
스크립트 파일의 선언 스코프
타입스크립트에서 “스크립트 파일”은 전역 스코프에서 실행됩니다. 즉, 파일 간에 명시적인 import나 export가 없으면, 모든 선언(변수, 함수 등)이 전역 스코프에 존재하게 됩니다. 따라서 한 스크립트 파일에서 선언된 변수가 다른 스크립트 파일과 충돌할 수 있습니다.
스크립트 파일의 특징:
전역 스코프에 존재.
다른 스크립트 파일에서도 동일한 이름의 변수를 선언할 수 없음.
서로 다른 파일에 동일한 변수를 선언하면 충돌이 발생.
// a.ts (스크립트 파일로 간주됨 - import/export 없음)
const shared = 'Cher';
// b.ts (또 다른 스크립트 파일)
const shared = 'Cher'; // 오류 발생: 이미 전역에 같은 이름의 변수가 존재
이 경우 타입스크립트는 shared 변수가 전역 스코프에서 중복 선언된 것으로 판단해 오류를 발생시킵니다.
ECMAScript 모듈의 선언 스코프
모듈 시스템을 사용할 때는 import와 export를 통해 각 파일이 모듈 단위로 동작하게 됩니다. 모듈 파일은 각각 자체적인 스코프를 가지며, 파일 간의 변수 충돌이 발생하지 않습니다. 즉, 파일 간의 이름 충돌은 피할 수 있습니다. 하지만 동일한 모듈 내에서 선언이 충돌하면 오류가 발생합니다.
모듈 파일의 특징:
파일이 모듈로 간주되면, 각 모듈은 자체적인 스코프를 가짐.
같은 이름의 변수를 여러 파일에서 선언해도 충돌이 발생하지 않음.
하지만 같은 파일 내에서 import된 변수와 동일한 이름의 변수를 다시 선언하면 오류가 발생.
// a.ts (모듈 파일)
export const shared = 'Cher';
// b.ts (모듈 파일)
export const shared = 'Cher';
// c.ts (모듈 파일)
import { shared } from './a'; // 'shared'는 'a.ts'에서 import됨
export const shared = 'Cher'; // 오류: 동일한 이름의 변수를 동일 파일에서 다시 선언할 수 없음
스크립트 파일: 전역 스코프를 공유하기 때문에 파일 간 변수 충돌이 발생할 수 있습니다.
모듈 파일: 파일 간에 독립된 스코프를 가지지만, 같은 파일 내에서 동일한 이름의 변수를 선언하면 오류가 발생합니다.
리터럴 타입
- 리터럴 타입(Literal Types)은 타입스크립트에서 더 구체적인 값으로 변수를 제한할 수 있는 기능입니다. 원시 타입(숫자, 문자열 등)의 특정 값 자체를 타입으로 사용하여, 특정 값만을 허용하는 방식입니다. 이를 통해 타입 안전성을 높이고 코드에서 명확한 제약을 설정할 수 있습니다.
let direction: 'left' | 'right' | 'up' | 'down';
direction = 'left'; // 가능
direction = 'up'; // 가능
direction = 'forward'; // 오류: 'forward'는 허용되지 않음
유니언 타입(|)과 인터섹션 타입(&)
- 유니언 타입은 두 개 이상의 타입 중 하나를 가질 수 있도록 허용합니다. 즉, 값이 여러 타입 중 하나를 선택할 수 있는 상황에서 사용됩니다.
type A = string | number;
let value: A;
value = "Hello"; // 문자열 할당 가능
value = 123; // 숫자 할당 가능
value = true; // 오류: boolean은 허용되지 않음
- 인터섹션 타입은 두 개 이상의 타입을 모두 만족해야 합니다. 즉, 타입들이 합쳐져서 모든 타입의 속성이나 메서드를 모두 갖는 하나의 타입이 됩니다.
```typescript
type B = { name: string } & { age: number };
let person: B;
person = { name: “John”, age: 30 }; // 가능
person = { name: “John” }; // 오류: age 속성이 없음
person = { age: 30 }; // 오류: name 속성이 없음
---
### strictNullChecks
엄격한 null 검사 활성화 / 비활성화: null 혹은 undefined 값을 참조/할당 했을 때 타입 에러 발생 여부
⇒ 10억 달러의 실수! (NullPointerException) ⇒ `strict: true`
> 폴더이름config.json의 `"strictNullChecks": true`로 해주자!!!!
엄격한 null 검사 활성화: 다른 타입이 필요한 위치에서 null 혹은 undefined 값을 참조/할당 하는 것을 방지한다! (즉, 활성화해야만 null 및 undefined에 대해한 오류로 부터 안전해진다!)
---
### 할당
```typescript
let xuser: {id: number, name: string};
xuser = {id: 1, name: 'xx'}; // OK
xuser = {id: 1}; // Error: name 속성이 없습니다
xuser = {id: 1, name: 'xx', age: 30}; // Error: {id, name, age}는 {id, name}에 할당할 수 없습니다.
첫 번째 할당에서는 {id: number, name: string} 타입과 정확히 일치하므로 문제가 없습니다.
두 번째 할당은 name 속성이 누락되어 오류가 발생합니다.
세 번째 할당은 추가 속성(age)이 포함되어 있어, 타입스크립트는 예상된 타입에 불필요한 속성이 있다고 판단해 오류를 발생시킵니다. 이는 신선함 검사(freshness check)에 의해 발생한 것입니다.
hong = {id: 1, name: 'Hong', addr: 'Pusan'} as TUser; // OK
as TUser를 사용하면 타입스크립트는 신선함 검사를 비활성화합니다. 이 경우, 타입스크립트는 이 객체가 TUser라고 간주하고, 추가된 속성 addr을 무시합니다. 즉, 타입 단언(assertion)을 사용해 추가된 속성 검사 오류를 무시할 수 있습니다.
CoVariance & ContraVariance
// strictFunctionTypes = true
function f(cb: (input: string | number)=> number) {return cb(1);}
function f2(input: string | number | boolean) {return 1;}
function f3(input: string | number) {return 1;}
function f4(input: string) {return 1;}
f(f2);
f(f3);
f(f4);
f 함수는 매개변수로 (input: string | number) => number 타입의 콜백 함수 cb를 받습니다. 즉, cb는 string 또는 number 타입의 입력을 받을 수 있어야 합니다.
f2는 string | number | boolean 타입의 매개변수를 받을 수 있습니다.
문제: f2는 boolean 타입도 받을 수 있는 콜백 함수이지만, f는 boolean을 허용하지 않습니다. 타입스크립트는 매개변수의 반공변성(contravariance) 때문에 더 넓은 타입(즉, boolean까지 포함하는 f2)을 더 좁은 타입(string | number만 허용하는 f)에 할당하는 것을 허용하지 않습니다.
요약: f2는 boolean 타입까지 허용하므로, f에 사용할 수 없습니다.
- 그러나 TypeScript는 실제로는 함수 매개변수의 반공변성을 완전히 엄격하게 적용하지 않고, 어떤 상황에서는 더 넓은 타입을 허용합니다. 이 경우, 매개변수 타입이 넓은 함수인 f2를 매개변수 타입이 좁은 함수인 f의 콜백으로 사용해도 오류가 발생하지 않습니다.
이런 허용은 TypeScript가 실무에서 좀 더 유연하게 사용될 수 있도록 일부러 설계된 부분입니다. 즉, TypeScript는 완전한 반공변성을 강제하지 않고, 보다 유연하게 함수 타입을 비교하는 경우가 있습니다.
f3는 string | number 타입을 매개변수로 받으며, 이는 f가 요구하는 타입과 일치합니다.
문제 없음: f3의 시그니처는 f의 요구 사항과 정확히 일치하므로, f(f3)는 정상적으로 작동합니다.
f4는 string만 매개변수로 받습니다.
문제: f4는 number 타입의 입력을 처리하지 못합니다. 하지만 f는 콜백 함수가 string | number 타입의 입력을 처리할 수 있어야 한다고 요구합니다. f는 number를 전달할 수 있지만, f4는 number를 허용하지 않기 때문에 오류가 발생합니다.
요약: f4는 number를 처리할 수 없기 때문에 f(f4)는 허용되지 않습니다.
0910 아침 정리
유니온 A | B는 A 또는 B가 할당 가능하다는 뜻 |
인터섹션 A&B는 A와B가 합쳐진 것