«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
Recent Posts
Recent Comments
관리 메뉴

뉴히의 개발 로그

[TIL] 20230727 - react-typeScript 프로젝트 생성 / typeScript 복습 타입스크립트 타입정리 및 예시 (기본타입,Tuple,union,intersection,void, never,enum,public, private, protected,abstract,Generic,keyof,Partial,Required,Readonly,Reco.. 본문

개발일지/TIL

[TIL] 20230727 - react-typeScript 프로젝트 생성 / typeScript 복습 타입스크립트 타입정리 및 예시 (기본타입,Tuple,union,intersection,void, never,enum,public, private, protected,abstract,Generic,keyof,Partial,Required,Readonly,Reco..

뉴히 2023. 7. 27. 20:34

리액트 타입스크립트 프로젝트 생성

공식문서 https://create-react-app.dev/docs/adding-typescript/

// npx를 사용하는 경우
npx create-react-app my-app --template typescript
// yarn을 사용하는 경우
yarn create react-app my-app --template typescript
기존 작업하던 리액트 프로젝트에서 시작

// npx를 사용하는 경우
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
// yarn을 사용하는 경우
yarn add typescript @types/node @types/react @types/react-dom @types/jest

 

 

프로젝트 생성 완료 !


기본타입

let age:number = 123;

let isAudult:blooean = true;

let a2:number[] = [1,2,3]

let a2:Array<number≥ [1,2,3];

let week1:string[] = [’mon’, ‘tue’, ‘wed’];

let week2:Array<string> = [’mon’, ‘tue’, ‘wed’];

함수 컴포넌트 리턴 타입 :React.FC

 

// 튜플 (Tuple)

let b : [string,number,boolean] = [’안녕’,’123’,true]

  • 타입선언한것과 순서가 동일하게 들어가야함
  • b[0].toUpperCase ⇒가능 (스트링타입이기 때문에 ) | b[1].toUpperCase ⇒ 오류!

// union | (또는)

type Job = ‘police’ | ‘developer’ | ‘teacher’;

 

// 교차타입 intersection types & (and)

interface Car {
	name: string;
	start(): void;
}

interface Toy {
	name: string;
	color: string;
	price: number;
}

const toyCar: Toy & Car = {
	// 모든 인터페이스의 속성을 적어줘야함
	name:'타요',
	start(){},
	color: 'blue',
	price: 1000
}

// void, never

콘솔만 찍히고 아무것도 반환하지 않을때 void 타입 사용

function sayhello(): void {
	console.log(’hello’);
}
에러만 찍히거나 계속 끝나지 않는 함수의 타입으로 never 사용

function showError(): never {
	throw new Error();
} 

function infLoop(): never {
	while(true){
		// do something..
	}
}

// enum : 비슷한 값끼리 묶어준것이라고 생각하면됨

enum Os {
	window, // 0
	Ios, // 1
	Android // 2
}
//  선언을 안해주면 자동으로 0,1,2... 으로 0부터 +1로 증가하면서 할당

enum Os {
	window =3, // 2
	Ios, // 4
	Android // 5
}

enum Os {
	window =3, // 2
	Ios=10, // 10
	Android // 11
}

양방향으로 맵핑되어있다!
console.log(OS['Ios'])   // 10
console.log(OS[10])   // 'Ios'
enum Os {
	window = 'win', 
	Ios ='ios', 
	Android = 'and' 
}
// String의 경우 단방향으로 맵핑된다
let myOs:Os;

myOs = Os.Window

enum Os 안에있는 값만 사용할 수 있다.

 

// null, undefined

let a:null = null;

let b:undefined = undefined;

 

 

객체 타입 생성 방법

  • interface
  • type

interface 프롭스명 extends 상위선언타입 { }

type 프롭스명 = 상위선언타입 & { }

type Score = 'A' | 'B' | 'C' | 'F' ;

interface User {
    name: string;
    age: number;
    gender?: string; // 옵셔널 처림 ? 있어도 되고 없어도 됨, 있을시에는 string
    readonly birthYear: number;
    // [grade(key-별의미없음): number]: string; // number를 키로 받고 string으로 value를 받겟다
		[grade: number]: Score; // string은 너무 방대하기때문에 타입을 새로 선언해서 A,B,C,F로 한정해서 지정할수있다.
}

let user: User = {
    name: '길동',
    age: 30,
    birthYear: 2000, //  readonly 타입 -> 생성시 할당
    1: 'A',
    2: 'B'
};

user.age = 10;
user.gender = 'male'
user.birthYear = 1990;  // 에러 ! readonly 속성이기 때문에 생성시에만 할당가능
* **interface로 함수 정의**

interface Add {
	(num1: number, num2:number) : nember ;  // (인자값1, 인자값2) : 리턴값의 타입
}

const add : Add = function(x, y) {  //num1, num2로 안받아도 됨!
	return x + y;
}

add(10, 20);  // 30

* **나이를 받아서 성인인지 아닌지 boolean 타입으로 리턴받는 함수** 

interface IsAdult {
	(age:number) : boolean;
}

const a:IsAdult = (age) =>{
	return age > 19;
}

a(33);  // true
// * **interface로 Class 정의**

interface Car {
	color: string;
	wheels: number;
	start(): void;
}

class Bmw implements Car {	
	color;
	wheels = 4;

****	// 생성시에 입력받기
	****constructor(c:string){
		this.color = c;
	}
	start(){
		console.log('go..')
	}
}

const b = new Bmw('green');

**// 확장**
interface Benz extends Car {
	door: number; // 추가 속성 
	stop(): void;
}

const benz: Benz = {
    door: 5,
    stop() {
        console.log('stop');
    },
    wheels: 4,
    color: 'red',
    start() {
        console.log('dd');
    }
}

**// 여러 인터페이스 동시 확장 가능**
interface Car {
	color: string;
	wheels: number;
	start(): void;
}

interface Toy {
	name: string;
}

interface ToyCar extends Car, Toy {
	price : number;
}

// 클래스 접근 제한자(Access modifier) - public, private, protected

  • public - 자식 클래스, 클래스 인스턴스 모두 접근 가능
  • protected - 자식 클래스에서 접근 가능
  • private - 해당 클래스 내부에서만 접근 가능 ⇒ private 대신 ‘#변수명’으로 사용 가능

readonly 속성 : public 에서 속성을 수정할 수 없고 읽기만 가능하게

⇒ 수정할 수 있게하려면 construtor 안에서 미리 작업을 할 수있게 만들어줘야함

static 속성 : 정적 멤버 변수를 만들 수 있다.

⇒ static으로 선언된 정적 멤버 변수나 메서드는 “this.변수명” 이 아니라 “클래스명.변수명” 으로 접근해야한다.

 

// 추상 class (abstract)

추상 클래스는 new를 이용해서 객체를 생성할 수 없다. extends(상속)을 통해서만 생성할 수 있다.

상속받은 객체에서 구체적인 기능을 꼭 정의해줘야한다!

abstract class Car {
	color: string;
	constructor(color: string) {
		this.color = color;
	}
	start() {
		console.log('start');
	}
	abstract doSomething():void; // 속성이나 메서드 이름만 선언! 자식 클래스 에서 정확한 기능 정의
}

// const car = new Car("red");  // 에러!!

class Bmw extends Car {
	constructor(color: string){
		super(color);    // super 없으면 에러남!!
	}
	doSometing(){ // abstract class를 상속받았으니 여기 구체적인 기능을 꼭! 정의해 줘야한다
		alert(3);
	}
}

// 제네릭 Generic : <T> 타입 파라메터, X or A등 사용해도 무관

  • 제네릭을 이용하면 클래스나 , 함수, 인터페이스를 다양한 타입으로 재사용 가능하다.
  • 선언시에는 type parameter만 정해주고 생성시점에 사용하는 타입을 결정!
function getSize<T>(arr: T[]): number {
	return arr.length;
}

const arr1 = [1,2,3];
getSize<number>(arr1); // 3
getSize<number | string>(arr1); 이렇게 사용 할 수도 있다. 

const arr2 = ['a','b','c'];
getSize<string>(arr2); // 3

const arr3 = [false, true, false];
getSize<boolean>(arr3); // 3

const arr4 = [{},{},{ name: 'Tim'}];
getSize<object>(arr4); // 3
// * interface에서 사용예시

interface Mobile<T> {
	name: string;
	price: number;
	option: T;
}

// const m1:Mobile<{color: string; coupon: boolean }> = { // 모습이 정해져 있으면 이렇게 해도 됨
const m1:Mobile<object> = {
	name: 's21';
	price: 1000;
	option: {
		color: 'red',
		coupon: false,
	},
};

const m2: Mobile<string> = {
	name: 's21';
	price: 1000;
	option: 'good'
};

 

 

유틸리티 타입

 

// keyof

interface User {
	id: number;
	name: string;
	age: number;
	gender: "m" | "f";
}

type UserKey = keyof User;  // 'id' | 'name' | 'age' | 'gender'

const uk: UserKey = "id";  // 이런식으로 쓸수 있움

// Partial<T>

  • property를 모두 옵셔널로 바꿔줌 ⇒ 일부만 사용 가능
  • 그외 속성을 추가하려하면 에러남!

// Required<T>

  • 모든 속성을 필수로 바꿔줌!

// Readonly<T>

  • 읽기 전용 속성으로 바꿔줌, 처음에 할당만 가능하고 후에 수정은 불가

// Record<K, T>

// 사용 예시

type Grade = "1" | "2" | "3" | "4";
type Score = "A" | "B" | "C" | "D" | "F";

const score: Record<Grade, Score> = {
	1: "A",
	2: "C",
	3: "B",
	4: "D"
}

// 사용 예시

interface User {
	id: number;
	name: string;
	age: number;
}

function isValid(user: User) {
	const result: Record<keyof User, boolean> = {
		id: user.id >0,
		name: user.name !== "",
		age: user.age > 0
	};
	return result;
}

// Pick<T,K> : T타입에서 K 속성만 골라서 사용

interface User {
	id: number;
	name: string;
	age: number;
	gender: "M" | "W";
}

const admin: Pick<User, "id" | "name"> = {
	id: 0,
	name: "Bob"
}

// Omit<T,K> : T타입에서 K 속성만 제외하고 사용

interface User {
	id: number;
	name: string;
	age: number;
	gender: "M" | "W";
}

const admin: Omit<User, "age" | "gender"> = {
	id: 0,
	name: "Bob"
}

// Exclude<T1, T2>

: Omit 은 속성만 제거, Exclude는 타입을 제거( 겹치는 타입을 제거)

type T1 = string | number | boolean;
type T2 = Exclude<T1, number | string>;  // T2는 boolean 만 남음

// NonNullable<Type>

: null, undefined 제외 시킴

type T1 = string | null | undefined | void;
type T2 = NonNullable<T1>;  // T2는 string | void 만 남음