타입스크립트 왜 쓸까?
타입스크립트는 코드에 목적(타입)을 명시하고,
맞지 않는 타입의 변수나 함수들에서 사전에 에러를 검출시킬 수 있습니다.
코드 자동완성이나 실행 전 피드백을 제공하여 작업과 동시에 디버깅이 가능해 생산성을 높일 수 있습니다.
// 타입스크립트 설치
npm i typescript
// node.js use
npm i -D ts-node
// tsconfig.json 설정
{
"compilerOptions": {
"target": "es5", //'es3', 'es5', 'es2015', 'es2016', 'es2017','es2018', 'esnext' 가능
"module": "commonjs", //무슨 import 문법 쓸건지 'commonjs', 'amd', 'es2015', 'esnext'
"allowJs": true, //js 파일들 ts에서 import해서 쓸 수 있는지
"checkJs": true, //일반 js 파일에서도 에러체크 여부
"jsx": "preserve", //tsx파일을 jsx로 어떻게 컴파일할 것인지'preserve','react-native','react'
"declaration": true, //컴파일시.d.ts파일도 자동으로 생성(현재쓰는 모든 타입이 정의된 파일)
"outFile": "./", //모든 ts파일을 js파일 하나로 컴파일해줌(module이 none, amd, system일 때만 가능)
"outDir": "./", //js파일 아웃풋 경로바꾸기
"rootDir": "./", //루트경로 바꾸기 (js 파일 아웃풋 경로에 영향줌)
"removeComments": true, //컴파일시 주석제거
"strict": true, //strict 관련, noimplicit 어쩌구 관련 모드 전부 켜기
"noImplicitAny": true, //any타입 금지 여부
"strictNullChecks": true, //null, undefined 타입에 이상한 짓 할시 에러내기
"strictFunctionTypes": true, //함수파라미터 타입체크 강하게
"strictPropertyInitialization": true, //class constructor 작성시 타입체크 강하게
"noImplicitThis": true, //this 키워드가 any 타입일 경우 에러내기
"alwaysStrict": true, //자바스크립트 "use strict" 모드 켜기
"noUnusedLocals": true, //쓰지않는 지역변수 있으면 에러내기
"noUnusedParameters": true, //쓰지않는 파라미터 있으면 에러내기
"noImplicitReturns": true, //함수에서 return 빼먹으면 에러내기
"noFallthroughCasesInSwitch": true, //switch문 이상하면 에러내기
}
}
// ts > js 자동변환
tsc -w
/* 변수 타입종류
1. string
2. number
3. boolean
4. null
5. undefined
6. bigint
7. [], {}
*/
// 변수 타입지정
let name_a :string = 'kim';
let name_b :{ name : string } = {name : 'kim'};
// object 타입 지정시 key 마지막에 ?를 붙인다면 null 허용
let names :string[] = ['kim', 'park'];
// 변수 다양한 타입지정
let name_c :string | number = 'kim';
let name_d :string[] | number = ['kim'];
// 타입 변수 지정
type MyType = string | number;
let name_e :MyType;
// Literal types(더 엄격한 타입 지정)
let 엄격한이름: 'kim';
let 엄격한숫자: 123;
let 접니다: '대희'|'조';
// All Type
let any :any;
let unknown :unknown;
// any 보다 unknown이 안전하다.
// any는 완전한 제약 해제이다.
// unknown - 1;
// 연산도 엄격한 제약 사항이 있다.
// array에 쓸 수 있는 tuple 타입
type MemberArr = [number, boolean];
let john :MemberArr = [123, true];
//---------------------------------------------------------------------
// 함수 타입지정
function fnc(x :number) :number {
return x * 2;
}
// 매게변수에 ?를 붙이면 x :number | undefined 의미이다.
function 함수_2(x :number) :number{
return x * 2;
}
// union type 에서 연산할때 type Narrowing을 써야한다.
function 함수_3(x :number|string){
if(typeof x === 'string'){
return x + '2';
}else{
return x + 1;
}
}
function 함수_4(x :number|string){
let array :number[] = [];
if(typeof x === 'number'){
array[0] = x;
}else{
// else문이 없다면 오류가 발생할 수 있다.
}
// assertion 문법(타입 덮어 쓰기)
array.push(x as number);
/*
1. Narrowing 일때만 쓴다.
2. 무슨 타입이 들어올지 100% 확실할 때 쓴다.
*/
}
// Literal Types
function 리터럴함수(a: 'hello') :1 | 0{
return 1;
}
// 함수표현식(함수 타입 as)
type 함수타입 = (a :string) => number;
let fncc :함수타입 = function (){
return 10;
}
// object 안에 함수 넣기
type CaType = (a :number) => number;
let 회원정보 = {
name : 'kim',
plusOne(a:number):number{
return a + 1;
},
changeName : () => {}
}
회원정보.plusOne(1);
// object 포괄 타입지정
type MemberObj = {
[key : string] : string,
}
// key와 value 는 string 타입이여야 한다.
// object type extend
type PositionX = {x:number};
type PositionY = {y:number};
type NewType = PositionX & PositionY;
let position :NewType = {x : 10, y :20};
// as const 를 object 뒤에 붙이면...
// 1. object value 값을 그대로 타입으로 지정해준다.
// 2. object 속성들에 모두 readonly 붙여준다.
var 자료 = {
name : 'kim'
} as const;
//---------------------------------------------------------------------
// 클래스 타입지정
class User {
name :string;
constructor(name :string){
this.name = name;
}
}
// ts 에서 constructor()를 사용하려면 필드값이 전역에 미리 있어야한다.
class Person {
name :string;
constructor(a :string){
this.name = a;
}
fnc(a :string){
console.log(a);
}
}
let 사람1 = new Person('kim');
let 사람2 = new Person('park');
// interface
// object 타입 부여 시 interface 의 extends(상속)를 사용할 수 있다.
interface Student {
name : string
}
interface Teacher extends Student {
age : number
}
let 학생 :Student = { name : 'kim'};
let 선생 :Teacher = { name : 'kim', age : 20};
// type 키워드에서는 아래와 같이 상속 한다.
type Animal_ = { name : string };
type Cat_ = { age : number } & Animal_;
// 하지만 & 는 상속의 개념이 아닌 교차의 의미이다.
// type vs interface
// 1. interface 중복선언 가능 / type 중복선언 불가능
// 중복선언 시 합쳐진다.
// 중복속성 부여 시
// 1. interface는 선안할때 오류가 발생
// 2. type는 사용할때 오류가 발생
// - interface가 좀 더 안정적이다.