조시 골드버그의 '러닝 타입스크립트' 책을 읽고 작성한 문서입니다.
Ch1. 자바스크립트에서 타입스크립트로
1.1 자바스크립트의 역사
1.3 타입스크립트
타입스크립트는 네 가지로 설명됩니다.
- 프로그래밍 언어: 자바스크립트의 모든 구문과, 타입을 정의하고 사용하기 위한 새로운 타입스크립트 고유 구문이 포함된 언어
- 타입 검사기: 자바스크립트 및 타입스크립트로 작성된 일련의 파일에서 생성된 모든 구성 요소 (변수, 함수 등) 를 이해하고, 잘못 구성된 부분을 알려주는 프로그램
- 컴파일러: 타입 검사기를 실행하고 문제를 보고한 후 이에 대응하는 자바스크립트 코드를 생성하는 프로그램
- 언어 서비스: 타입 검사기를 사용해 비주얼 스튜디오 코드와 같은 편집기에 개발자에게 유용한 유틸리티 제공법을 알려주는 프로그램
1.4 타입스크립트 플레이그라운드에서 시작하기
플레이그라운드 편집기: https://www.typescriptlang.org/ko/play
플레이그라운스는 타입스크립트 코드가 자바스크립트로 어떻게 출력되는지 보여주는 훌륭한 도구입니다.
많은 자바스크립트 프로젝트는 소스 코드를 실행할 수 있는 자바스크립트로 변환하기 위해서 타입스크립트의 자체 컴파일러 대신 '바벨 (https://babeljs.io)' 과 같은 전용 변환기를 사용합니다.
1.5 로컬에서 시작하기
typescript 설치
npm i -g typescript
이제 명령줄에서 tsc (타입스크립트 컴파일러) 명령어로 타입스크립트를 실행할 수 있습니다.
--version 플래그를 사용해 타입스크립트가 올바르게 설정되었는지 확인합시다.
신규 tsconfig.json 구성 파일을 생성합니다.
tsc --init
tsconfig.json 파일은 타입스크립트가 코드를 분석할 때 사용하는 설정을 선업합니다.
13장 '구성 옵션' 에서 tsconfig.json 파일의 옵션을 간략하게 살펴봅니다. 여기서 알고 가야 할 중요한 특징은 tsc 를 실행해 폴더의 모든 파일을 컴파일하도록 지시할 수 있고, 타입스크립트가 모든 구성 옵션에 대해서 tsconfig.json 을 참조할 수 있다는 것입니다.
다음 내용이 포함된 index.ts 파일을 추가합니다.
1.5.2 편집기 기능
tsconfig.json 파일을 생성할 때의 또 다른 이점은 편집기에서 특정 폴더를 열었을 때, 편집기가 이제 해당 폴더를 열면 타입스크립트 프로젝트로 인식한다는 것입니다. 예를 들어 VS Code 에서 폴더를 열면 타입스크립트 코드를 분석하는 데 사용하는 설정은 해당 폴더의 tsconfig.json 을 따르게 됩니다.
1.6 타입스크립트에 대한 오해
1.6.2 자바스크립트로의 확장
타입스크립트의 설계 목표
- 현재와 미래의 ECMA 스크립트 제안에 맞춘다.
- 모든 자바스크립트 코드의 런타임 동작을 유지한다.
1.6.3 자바스크립트보다 느림
ts-node 와 디노처럼 타입스크립트 코드를 직접 실행하는 것처럼 보이는 프로젝트에서도, 실행하기 전에 내부적으로 타입스크립트 코드를 자바스크립트로 변환합니다.
1.6.4 진화가 끝남
이 책은 집필 시점 기준 최신 버전인 4.7.2 버전으로 출판되었다.
2024/03/30 기준 최신버전은 5.3
1.7 마치며
https://www.learningtypescript.com/from-javascript-to-typescript 에서 배운 내용을 연습해보세요.
Ch2. 타입 시스템
2.1 타입의 종류
일곱가지 원시타입
- null
- undefined
- boolean
- string
- number
- bigint
- symbol
타입스크립트에서는 일반적으로 boolean 과 number 처럼 소문자로 참조하는 것이 모범 사례입니다.
2.1.2 오류 종류
- 구문 오류
- 타입 오류
구문 오류
타입스크립트가 코드로 이해할 수 없는 잘못된 구문을 감지할 때 발생
타입 오류
타입스크립트의 타입 검사기가 프로그램의 타입에서 오류를 감지했을 때 발생
2.2 할당 가능성
2.3 타입 애너테이션
타입스크립트는 초기값을 할당하지 않고도 변수의 타입을 선언할 수 있는 구문인 타입 애너테이션을 제공합니다.
2.3.1 불필요한 타입 애너테이션
필자를 포함한 많은 개발자는 아무것도 변하지 않는 변수에는 타입 애너테이션을 추가하지 않기를 선호합니다.
2.4 타입 형태
2.4.1 모듈
ECMA 스크립트 2015 에는 파일을 가져오고 내보내는 구문을 표준화하기 위해 ECMA 스크립트 모듈 (ESM) 이 추가되었습니다.
- 모듈: export 또는 import 가 있는 파일
- 스크립트: 모듈이 아닌 모든 파일
모듈 파일에 선언된 모든 것은 해당 파일에서 명시한 export 문에서 내보내지 않는 한 모듈 파일에서만 사용할 수 있습니다.
그러나 파일이 스크립트면 타입스크립트는 해당 파일을 전역 스코프로 간주하므로 모든 스크립트가 파일의 내용에 젖ㅂ근할 수 있습니다. 즉, 스크립트 파일에 선언된 변수는 다른 스크립트 파일에 선언된 변수와 동일한 이름을 가질 수 없습니다.
파일을 모듈로 만드려면 아무 곳에나 export {} 를 추가해 강제로 모듈이 되도록 만듭니다.
const shared = "Cher"
export {}
타입스크립트는 CommonJS 와 같이 이전 모듈을 사용해서 작성된 타입스크립트 파일의 import, export 형태는 인식하지 못합니다. 타입스크립트는 일반적으로 CommonJS 스타일의 require 함수에서 반환된 값을 any 타입으로 인식합니다.
Ch3. 유니언과 리터럴
- 유니언: 값에 허용된 타입을 두 개 이상의 가능한 타입으로 확장하는 것
- 내로잉: 값에 허용된 타입이 하나 이상의 가능한 타입이 되지 않도록 좁히는 것
3.1 유니언 타입
3.1.2 유니언 속성
유니언으로 선언한 모든 가능한 타입에 존재하는 멤버 속성에만 접근할 수 있습니다.
3.2 내로잉
타입을 좁히는 데 사용할 수 있는 논리적 검사를 타입 가드 라고 합니다.
3.2.2 조건 검사를 통한 내로잉
if 문 안에서
3.2.3 typeof 검사를 통한 내로잉
if 문과 type of
3.3 리터럴 타입
지금부터는 리터럴 타입 (literal type) 을 소개하겠습니다. 리터럴 타입은 좀 더 구체적인 버전의 원시 타입입니다.
3.4 엄격한 null 검사
3.4.1 십억 달러의 실수
'십억 달러의 실수' 는 다른 타입이 필요한 위치에서 null 값을 사용하도록 허용하는 많은 타입시스템을 가리키는 업계 용어입니다.
타입스크립트 컴파일러는 실행 방식을 변경할 수 있는 다양한 옵션을 제공합니다.
가장 유용한 옵션 중 하나인 strictNullChecks 는 엄격한 null 검사를 활성화할지 여부를 결정합니다.
모범 사례는 일반적으로 엄격한 null 검사를 활성화하는 것입니다.
3.4.2 참 검사를 통한 내로잉
자바스크립트에서 false, 0, -0, 0n, "", null, undefined, NaN 처럼 falsy 로 정의된 값을 제외한 모든 값은 모두 참입니다.
let biologist = Math.random() > 0.5 && 'Rachel Carson'
if (biologist) { // 빈 문자열이라면 false 가 됨
biologist // string
} else {
biologist // false | string
}
3.5 타입 별칭
타입스크립트에는 재사용하는 타입에 더 쉬운 이름을 할당하는 타입 별칭이 있습니다.
편의상 타입 별칭은 파스칼 케이스로 이름을 지정합니다.
3.5.1 타입 별칭은 자바스크립트가 아닙니다
타입 별칭은 순전히 타입 시스템에만 존재하므로 런타임 코드에서는 참조할 수 없습니다. 타입스크립트는 런타임에 존재하지 않는 항목에 접근하려고 하면 타입 오류로 알려줍니다.
다시 말하지만 타입 별칭은 순전히 '개발 시'에만 존재합니다.
Ch4. 객체
4.1 객체 타입
4.1.1 객체 타입 선언
let poetLater: {
born: number
name: string
}
poetLater = {
born: 1935,
name: 'Mary Oliver',
}
4.1.2 별칭 객체 타입
각 객체 타입에 타입 별칭을 할당해 사용하는 방법이 더 일반적입니다.
대부분 타입스크립트 프로젝트는 객체 타입을 설명할 때 인터페이스 키워드를 사용하는 것을 선호합니다.
별칭 객체 타입과 인터페이스는 거의 동일합니다.
4.2 구조적 타이핑
구조적 타이핑은 덕 타이핑과는 다릅니다.
요약하면 자바스크립트는 덕 타입인 반면 타입스크립트는 구조적으로 타입화됩니다.
4.2.2 초과 속성 검사
초과 속성 검사는 객체 타입으로 선언된 위치에서 생성되는 객체 리터럴에 대해서만 일어납니다. 기존 객체 리터럴을 제공하면 초과 속성 검사를 우회합니다.
4.2.4 선택적 속성
선택적 속성과 undefined 를 포함한 유니언 타입의 속성 사이에는 차이가 있음을 명시하세요. ? 를 사용해 선택적으로 선언된 속성은 존재하지 않아도 됩니다. 필수로 선언된 속성과 } undefined 는 그 값이 undefined 일지라도 반드시 존재해야 합니다.
4.3 객체 타입 유니언
4.3.2 명시된 객체 타입 유니언
객체 타입 유니언도 타입을 좁혀야 합니다.
4.3.3 객체 타입 내로잉
in keyword
type PoemWithPages = {
name: string
pages: number
}
type PoemWithRhymes = {
name: string
rhymes: boolean
}
type Poem = PoemWithPages | PoemWithRhymes
const poem: Poem =
Math.random() > 0.5
? { name: 'The Double Image', pages: 7 }
: { name: 'Her Kind', rhymes: true }
if ('pages' in poem) {
poem.pages
} else {
poem.rhymes
}
4.3.4 판별된 유니언
객체의 또 다른 인기 있는 형태는 객체의 속성이 객체의 형태를 나타내도록 하는 것입니다. 이러한 타입 형태를 판별된 유니언이라 부르고, 객체의 타입을 가리키는 속성이 판별값입니다.
4.4 교차 타입
타입스크립트에서도 & 교차 타입을 사용해 여러 타입을 동시에 나타냅니다.
type Artwork = {
genre: string
name: string
}
type Writing = {
pages: number
name: string
}
type WrittenArt = Artwork & Writing
/*
{
genre: string
name: string
pages: number
}
*/
4.4.1 교차 타입의 위험성
never
교차 타입은 잘못 사용하기 쉽고 불가능한 타입을 생성합니다.
대부분의 타입스크립트 프로젝트는 never 타입을 거의 사용하지 않지만 코드에서 불가능한 상태를 나타내기 위해 가끔 등장합니다.
Ch5. 함수
5.1 함수 매개변수
5.1.2 선택적 매개변수
5.1.3 기본 매개변수
매개변수에 기본값이 있고 타입 애너테이션이 없는 경우, 타입스크립트는 해당 기본값을 기반으로 매개변수 타입을 유추합니다.
초기값이 있으면 타입과 ? 가 없어도 된다.
5.1.4 나머지 매개변수
배열타입처럼 보이지만 배열을 넣을 수 없다.
5.2 반환 타입
5.2.1 명시적 반환 타입
변수와 마찬가지로 타입 애너테이션을 사용해 함수의 반환 타입을 명시적으로 선언하지 않는 것이 좋습니다.
명시적으로 선언하는 방식이 매우 유용할 때가 있습니다.
- 가능한 반환값이 많은 함수가 항상 동일한 타입의 값을 반환하도록 강제
- 재귀 함수의 반환 타입을 통해 타입을 유추하는 것을 거부
- 수백 개 이상의 타입스크립트 파일이 있는 매우 큰 프로젝트에서 타입스크립트 검사 속도 높임
5.3 함수 타입
자바스크립트에서는 함수를 값으로 전달할 수 있습니다. 함수 타입 (function type) 구문은 화살표 함수와 유사하지만 함수 본문 대신 타입이 있습니다.
함수 타입은 콜백 매개변수 (함수로 호출되는 매개변수) 를 설명하는 데 자주 사용됩니다.
import { log } from "console";
const songs = ['Juice', 'Shake It Off']
function runOnSongs(getSongAt:(index: number) => string) {
for (let i = 0; i < songs.length; i++) {
log(getSongAt(i))
}
}
function getSongAt(index:number) {
return `${songs[index]}`
}
runOnSongs(getSongAt)
함수의 매개변수로 함수를 넣을 때는 괄호가 없어도 됨
5.3.1 함수 타입 괄호
유니언 타입의 애너테이션에서 함수 반환 위치를 나타내거나 유니언 타입을 감싸는 부분을 표시할 때 괄호를 사용합니다.
let returnsStringOrUndefined: () => string | undefined
let maybeReturnsString: (() => string) | undefined
5.3.2 매개변수 타입 추론
매개변수로 사용되는 인라인 함수 (inline function) 을 포함하여 작성한 모든 함수에 대해 매개변수를 선언해야 한다면 번거로울 것입니다.
let singer: (song: string) => string
singer = function(song) {
return `Singing: ${song.toUpperCase()}!`
}
배열의 내장함수 forEach
import { log } from "console"
const songs = ['Call Me', 'Jolene', 'The Chain']
songs.forEach((song, index) => {
log(`${song} is at index ${index}`)
})
5.3.3 함수 타입 별칭
type StringToNumber = (input: string) => number
let stringToNumber: StringToNumber
stringToNumber = (input) => input.length
타입 별칭은 특히 함수 타입에 유용합니다. 타입 별칭을 이용하면 반복적으로 작성하는 매개변수와 반환 타입을 갖는 코드 공간을 많이 절약할 수 있습니다.
5.4 그 외 반환 타입
지금부터 void 와 never, 두 반환 타입에 대해 알아봅시다.
5.4.1 void 반환 타입
일부 함수는 어떤 값도 반환하지 않습니다. 예를 들면 return 문이 없는 함수이거나 값을 반환하지 않는 return 문을 가진 함수일 경우입니다.
return type 을 void 로 선언하고 return value 를 하면 컴파일 에러가 난다.
예를 들어 배열의 내장 forEach 메서드는 void 를 반환하는 콜백을 받습니다. forEach 에 제공되는 함수는 원하는 모든 값을 반환할 수 있습니다.
void 타입은 함수의 반환값이 자체적으로 반환될 수 있는 값도 아니고, 사용하기 위한 것도 아니라는 표시임을 기억하세요.
5.4.2 never 반환 타입
nuver 는 void 와는 다릅니다. void 는 아무것도 반환하지 않는 함수를 위한 것이고, never 는 절대 반환하지 않는 함수를 위한 것입니다.
5.5 함수 오버로드
일부 자바스크립트 함수는 선택적 매개변수와 나머지 매개변수만으로 표현할 수 없는 매우 다른 매개변수들로 호출될 수 있습니다. 이러한 함수는 오버로드 시그니처 (overload signature) 라고 불리는 타입스크립트 구문으로 설명할 수 있습니다. 즉, 하나의 최종 구현 시그니처와 그 함수의 본문 앞에 서로 다른 버전의 함수 이름, 매개변수, 반환 타입을 여러 번 선언합니다.
함수의 이름은 같고, 매개변수가 다른 경우
컴파일해 자바스크립트로 출력하면 다른 타입 시스템 구문처럼 오버로드 시그니처도 지워집니다.
5.5.1 호출 시그니처 호환성
구현 시그니처는 모든 오버로드 시그니처와 호환되어야 합니다.
앞에서부터 같은 매개변수여야 한다.
Ch6. 배열
타입스크립트가 초기 배열에 담긴 요소를 통해 배열의 타입을 유추하는 방법은 변수의 초깃값에서 변수 타입을 유추하는 방법과 유사합니다.
6.1 배열 타입
6.1.4 다차원 배열
2차원 배열 또는 배열은 두개의 [] (대괄호) 를 갖습니다.
6.2 배열 멤버
6.2.1 주의 사항: 불안정한 멤버
자바스크립트에서조차도 배열의 길이보다 큰 인덱스로 배열 요소에 접근하몀ㄴ undefined 를 제공합니다.
타입스크립트에서는 배열 조회를 더 제한하고 타입을 안전하게 만드는 noUncheckedIndexedAccess 플래그가 있지만 이 플래그는 매우 엄격해서 대부분 프로젝트에서 사용하지 않습니다.
6.3 스프레드와 나머지 매개변수
6.3.1 스프레드
... 스프레드 연산자를 사용해 배열을 결합합니다.
6.4 튜플
튜플 타입을 선언하는 구문은 배열 리터럴처럼 보이지만 요소의 값 대신 타입을 적습니다.
6.4.1 튜플 할당 가능성
import { log } from "console";
function logPair(name:string, value: number) {
log(`${name} has ${value}`)
}
const pairTupleCorrect: [string, number] = ['Amage', 1]
logPair(...pairTupleCorrect)
튜플을 ... 로 할당할 수 있다.
6.4.2 튜플 추론
타입스크립트는 생성된 배열을 튜플이 아닌 가변 길이의 배열로 취급합니다.
타입스크립트에서는 값이 일반적인 배열 타입 대신 좀 더 구체적인 튜플 타입이어야 함을 다음 두 가지 방법으로 나타냅니다. 명시적 튜플 타입과 const 어서션 (assertion) 을 사용한 방법입니다.
const 어서션
return 에 as const 을 사용할 수 있다.
const readonlyTuple = [1157, 'Tomoe'] as const
실제로 읽기 전용 튜플은 함수 반환에 편리합니다. 튜플을 반환하는 함수로부터 반환된 값은 보통 즉시 구조화되지 않으므로 읽기 전용인 튜플은 함수를 사용하는 데 방해가 되지 않습니다.
import { log } from "console"
function firstCharAndSizeAsConst(input:string) {
return [input[0], input.length] as const
}
const [firstChar, size] = firstCharAndSizeAsConst('Ching Shih')
log(firstChar, size)
Ch7. 인터페이스
Ch8. 클래스
Ch9. 타입 제한자
Ch10. 제네릭
Ch11. 선언 파일
Ch12. IDE 기능 사용
Ch13. 구성 옵션
Ch14. 구문 확장
Ch15. 타입 운영
'Backend > 노트' 카테고리의 다른 글
NestJS 로 배우는 백엔드 프로그래밍 (0) | 2024.03.31 |
---|---|
NestJS로 API 만들기 (1) | 2024.03.26 |
파이썬으로 개발하는 빅데이터 기반 맛집 추천 서비스 (ft. Django, FastAPI) 초격차 패키지 Online (0) | 2023.12.22 |
FastAPI 를 사용한 파이썬 웹 개발 (2) | 2023.12.01 |
고랭 애플로그인 구현 (golang apple login) (0) | 2023.05.06 |