TypeScript_Setting+기본-1

김정훈·2023년 7월 18일
0
post-thumbnail
post-custom-banner

코드에디터에서 TypeScript PlayGround세팅

  1. node설치
  2. node -v / npm -v 버전 확인하기
  3. 폴더 안에서 npm init -y // 그럼 폴더가 node 프로젝트가 된다.
  4. npm i typescript
  5. npx tsc --init // tsconfig.json이 생긴다.
  6. tsconfig.json 파일에서 allowJs: true, strict: true
  7. npx tsc // ts파일을 js파일로 바꿔준다.
  • tsconfig.json
    forceConsistentCasingInFileNames : true :대소문자 구분하는 속성
    skipLibCheck: true : 사용하는 라이브러리 타입만 체크해라

타입스크립트는 변수, 매개변수, 리턴값에 타입 붙이는 것

기본적인 Type작성하기

const a: string = '5';
const b: number = 5;
const c: boolean = true;
const d: undefined = undefined;
const e: null = null;

const f: true = true; // true값만 받을 것 이다.

type으로 타입을 선언하는 방식 (type alias)

type Add = (x:number, y:number) => number; // 이 코드를 함수에 바로 쓰면 밑에 코드처럼
const add: (x:number, y:number) => number = (x,y) => x+y; // 1번 코드
const add2: Add = (x,y) => x+y; // 1번 코드와 동일하다.
// VanillaJs : const add = (x,y) => x+y;

const obj: { lat: number, lon: number } = { lat: 37.5, lon: 127.5 };
// const obj = {lat: 37.5, lon: 127.5};

const arr: string[] = ['123','456'];
const arr2: number[] = [123, 456];
const arr3: Array<number> = [789, 012];
const arr4: [number, number,string] = [123,456,'hello'];

function add(x: number, y: number): number { return x + y }
function add(x,y){ return x+y }

타입 추론을 적극 활용하자

const는 타입스크립트가 타입 추론을 한다.
let에 타입을 주로 정의하는 작업이 필요하다.
TypeScriptany로 추론하면 그 부분은 꼭 정의해주자.


js 변환 시 사라지는 부분을 파악하자.

TypeScript에서 Javascript로 변환할 때

const f:true = true; // :true가 사라짐
type Add = () => number;
interface Minus{}
Array<string>
as
enum
declare

이런 부분들이 다 사라진다.
→ 위에 3가지가 없이도 잘 돌아가게 만들어야 한다. 결국 JavaScript로 실행되기 때문에.

이런 방법도 가능

function add(x:number, y:number): number;
function add(x,y){
	return x+y;
}

억지로 바꾸는 경우?

let aa = 123;
aa = 'hello' as unknown as number;

never타입과 느낌표

never라는 타입이 나온다.
https://ui.toast.com/weekly-pick/ko_20220323

try{
	// const array=[]; //이 상태라면 never가 나오고 typescript가 오류를 발생시킴
	const array: string[] = [];
	array.push('hello');
} catch(error){
	error;
}

! 느낌표
: !는 안 쓰는 것을 추천- null or undefined일리가 없다고 확신하는 뜻.

const head = document.querySelector("#head")!;
// 설명 : head는 null혹은 undefined일리가 없다. 확실하다.

원시 래퍼 타입, 템플릿 리터럴 타입, rest, 튜플

type World = "world" | "hell";
const a: World = 'world';

const b = `hello ${a}`;

type Greeting = hello ${World};
const c: Greeting = 'hell';

Rest파라미터+Ts

function rest(a, ...args: string[]){
	console.log(a, args);
}

rest('1', '2', '3');

Ts가 못 잡아주는 에러 : 튜플

// 튜플은 길이가 정해져 있는 배열
const tuple: [string, number] = ['1', 1];

tupel[2] = 'hello'; // 에러 띄워준다. - 3번째 추가 불가능.

tuple.push('hello') // 못 잡아줌 - 똑같이 3번째 추가하는 코드인데.

enum, keyof, typeof

enum 여러 개의 변수들을 하나의 그룹으로 묶고 싶을때 보통 사용한다.

// 선택지1 : Enum
const enum Edit{
	Up,
	Down,
	Left,
	Right,
}
function walk(dir: Edit){}

// 선택지2 : Enum없이 사용
const ODit{
	Up: 0,
	Down: 1,
	Left: 2,
	Right: 3,
} as const;
type Direction = typeof ODit[keyof typeof ODit];
function run(dir: Direction){}

const a = EDit.Up;
const c = Edit.Left;

walk(EDit.Left);
run(ODit.Right);

key, value 뽑아내기

const obj = {a:'123', b:'hello', c:'world'} //as const 유무에 따라서 value값이 결정됨(string인지 아니면 엄격하게 '123','hello','world'인지);
type Key = keyof typeof obj;

type Value = typeof obj[keyof typeof obj];

union(|)과 intersection(&)

타입 정의

type A={ a: string}
const a: A = {a:'hello'};

union : or( | )

function add(x: string | number, y:string | number) : string | number
{ return x+y; }
/*
⭐️⭐️⭐️ 애초에 x: string, y: number라면 연산자체가 불가능
→ Ts에서 에러를 발생시킨다. Ts에서는 다양한 상황을 고려하기 때문에 애초에 위와 같은 union을 사용해서 하고 싶다면 다음과 같이 코드를 작성해야 한다.
*/
function add5(x: string | number, y: string | number): string | number {
    if (typeof x === 'number' && typeof y === 'number') {
      return x + y; // 두 숫자를 더해서 숫자를 반환
    } else {
      return String(x) + String(y); // 그 외에는 문자열로 변환하여 연결
    }
}

⭐️⭐️⭐️ 처음에 타입정의를 잘못하면 끝도 없이 꼬인다.
엄격하게 타입을 정의하자!

intersection : and( & )

type A = {hello: 'world'} & {zero:'cho'};
const a: A={hello: 'world', zero:'cho'}; // 둘 다 만족하는 경우+하나만 만족해도 가능
const b: A={hello:'world'} // 하나만 만족하는 경우

타입 애일리어스와 인터페이스의 상속(extends)

Type 정의

type Animal = {breath: true};
type Poyouryu = Animal & {breed: true};
type Human = Poyouryu & {think: true};

const tester: Human = { breath: true, breed: true, think: true};

Interface사용 : 확장에 용이하다.

interface A{
	breath: true
}
interface B extends A{
	breed: true
}

const b: B = {breath: true, breed: true};

// 중복 선언 가능 확장?
interface C{
	talk: () => void;
}
interface C{
	eat: () => void;
}
interface C{
	shit: () => void;
}
const test: C = {talk() {}, eat() {}, shit() {}}

// C 라이브러리에 exercise을 추가하고 싶다.
interface C{
	exercise: () => void;
}

const player: C = {talk() {}, eat() {}, shit() {}, exercise(){}}

타입스크립트 네이밍 : 요즘은 I, T, E를 안 붙이는 경우가 많음

interface ISomething
type TSomething
enum ESomething

타입을 집합으로 생각하자(좁은 타입과 넓은 타입)

좁은 타입은 넓은 타입으로 대입이 가능

// A에서 B로 대입 가능하다.
//작은 타입
type A = string;

//큰 타입
type B = string | number;

객체는 상세할수록 좁은 타입이다.

type A = {name: string};
type B = {age: number};
type C = {name: string, age: number}; // 가장 좁은 타입이다.

type AB = A | B;
type CC = A & B;

const ab: AB = {name: 'zerocho'};
const c: CC = {name: 'chocho', age: 29};

const ab:AB=c; // 좁은 타입을 넓은 타입으로 대입 : 가능
const c:C=ab; // 넓은 타입을 좁은 타입으로 대입 : 불가능

객체에서 잉여속성 검사를 피하는 방법

type A = {name: string};
type B = {age: number};
type C = A&B;

const c: C = {name: 'test', age: 29, married: false}
/*
에러를 발생시킨다.
잉여속성 검사가 일어난다.
married라는 속성이 A,B에 정의되있지 않기 때문이다.
*/

// 잉여 속성 검사를 피하기 위해서는 이렇게 써야한다.
const obj = { name:'test', age: 29, married: false}
const c: C = obj;
profile
WebDeveloper
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

좋은 글 감사합니다!

답글 달기