타입스크립트
- 함수 오버로드
함수의 매개변수가 여러 타입을 가져서 리턴 값의 타입이 하나로 정해져있지 않을 때 사용할 수 있다.
interface User {
name: string,
age: number;
}
function join(name: string, age: string): string;
function join(name: string, age: number): User;
function join(name: string, age: number | string): User | string {
if(typeof age === 'number') {
return {
name,
age
};
} else {
return "나이는 숫자로 입력해주세요.";
}
}
const sam: User = join("Sam", 30);
const hane: string = join("Jane", "30");
- 문자열 리터럴 타입
const userName1 = "Bob";
let userName2 = "Tom";
const의 경우 변할 수 없는 상수이기 때문에 타입추론이 "Bob"으로 된다. Bob이외의 값은 설정할 수 없기 때문에! 이런 것을 문자열 리터럴 타입이라고 한다. 이와 반대로 let 키워드로 변수를 선언하면 값이 바뀔 수 있기때문에 string으로 타입추론이 된다.
- class
class Car {
color:string; //타입 선언
constructor(color: string) {
this.color = color;
}
start() {
console.log("start")
}
}
- 접근 제한자 - public, private, protected
타입스크립트에서는 접근 제한자를 제공한다.
public: 자식 클래스나 인스턴스에서 접근이 가능하다. 아무 것도 적지 않을 경우 public 이 기본 값
private: 해당 클래스 내부에서만 사용 가능하다. #으로 작성해도 된다.
protected: 자식 클래스에서 접근 가능하나 인스턴스에서는 사용할 수 없다.
- 추상 클래스
추상 클래스는 new로 인스턴스를 생성할 수 없고 오직 상속만 가능하다.
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 {
constrcutor(color: string) {
super(color);
}
doSomthing(){
alert(3);
}
}
const z4 = new Bmw("black");
추상 클래스의 메서드를 추상화한다는 것은 상속받은 자식 클래스들이 모두 동일한 이름의 메서드를 가지고 있지만 내부 로직은 독자적이라는 것을 의미한다. 따라서 추상 클래스 내의 추상 메서드는 이름만 선언하고, 자식 클래스에서는 해당 메서드에 대한 로직을 꼭 적어주어야 한다.
- 제네릭
interface User {
name: string;
age: number;
}
interface Car {
name: string;
color: string;
}
interface Book {
price: number;
}
const user: User = {name: "a", age: 10};
const car: Car = {name: "bmw", age: "red"};
const book: Book = {price: 3000};
function showName<T extends { name: string }>(data: T): string {
return data.name;
}
showName(user);
showName(car);
showName(book); //에러
<T extends { name: string }>의 의미는 T는 {name: string}의 확장된 형태라는 것. 즉 다양한 객체가 들어올 수 있어도 그 객체는 무조건 타입이 string인 name 프로퍼티를 가진 객체여야 한다는 의미이다. 따라서 book 에는 ame객체가 없기 때문에 showName(book)을 했을 때 에러가 나게 된다.
- Partical<T>
: T의 내용을 옵셔널로 갖는다.
interface User {
id: number;
name: string;
age: number;
gender: "m" | "f";
}
let admin: Partical<User> = {
id: 1,
name: "Bob"
}
위의 코드는
interface User {
id?: number;
name?: string;
age?: number;
gender?: "m" | "f";
}
이렇게 사용하는 것과 같다. 그래서 여기 없는 프로퍼티를 사용하려고 하면 에러가 난다.
- Required<T>
Partical 과 반대로 모든 프로퍼티가 사용되어야 한다.
interface User {
id: number;
name: string;
age?: number;
}
let admin: Required<User> = {
id: 1,
name: "Bob",
age: 30
}
이렇게 interface에서 age가 옵셔널이어도 Required로 사용하면 필수 프로퍼티가 된다.
- Readonly<T>
: 이후의 수정이 불가능해진다.
interface User {
id: number;
name: string;
age?: number;
}
let admin: Readonly<User> = {
id: 1,
name: "Bob",
}
admin.id = 4; //에러
이렇게 Readonly이기 때문에 이후에 수정하는 것이 불가능하다.
- Record<K, T>
K는 key이고 T는 Type으로 key에는 K에 해당하는 것이 포함되고 타입은 T에 해당하는 것에 포함되면 된다.
interface Score {
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
}
const scor: Score = {
1: "A",
2: "C",
3: "B",
4: "D"
}
이렇게 작성되어 있는 것을 Record를 사용하면 반복을 조금 줄일 수 있다.
type Grade = "1"|"2"|"3"|"4";
type Score = "A"|"B"|"C"|"D";
const score: Record<Grade, Score> = {
1: "A",
2: "C",
3: "B",
4: "D"
}
Grade를 key로 Score를 Type으로 사용하는 것이다.
- NonNullable<Type>
null을 제외한 타입을 사용하는 것
type T1 = string | null | undefined | void;
type T2 = NonNullable<T>;
이런 경우 T2는 string 혹은 void만 타입으로 가지게 된다.
'일상 > Today I Learned' 카테고리의 다른 글
2023.02.01 (0) | 2023.02.01 |
---|---|
2023.01.31 (0) | 2023.01.31 |
[데브코스 Day53] 2022.12.28 (0) | 2022.12.28 |
[데브코스 Day52] 2022.12.27 (0) | 2022.12.27 |
[데브코스 Day51] 2022.12.26 (0) | 2022.12.26 |
타입스크립트
- 함수 오버로드
함수의 매개변수가 여러 타입을 가져서 리턴 값의 타입이 하나로 정해져있지 않을 때 사용할 수 있다.
interface User {
name: string,
age: number;
}
function join(name: string, age: string): string;
function join(name: string, age: number): User;
function join(name: string, age: number | string): User | string {
if(typeof age === 'number') {
return {
name,
age
};
} else {
return "나이는 숫자로 입력해주세요.";
}
}
const sam: User = join("Sam", 30);
const hane: string = join("Jane", "30");
- 문자열 리터럴 타입
const userName1 = "Bob";
let userName2 = "Tom";
const의 경우 변할 수 없는 상수이기 때문에 타입추론이 "Bob"으로 된다. Bob이외의 값은 설정할 수 없기 때문에! 이런 것을 문자열 리터럴 타입이라고 한다. 이와 반대로 let 키워드로 변수를 선언하면 값이 바뀔 수 있기때문에 string으로 타입추론이 된다.
- class
class Car {
color:string; //타입 선언
constructor(color: string) {
this.color = color;
}
start() {
console.log("start")
}
}
- 접근 제한자 - public, private, protected
타입스크립트에서는 접근 제한자를 제공한다.
public: 자식 클래스나 인스턴스에서 접근이 가능하다. 아무 것도 적지 않을 경우 public 이 기본 값
private: 해당 클래스 내부에서만 사용 가능하다. #으로 작성해도 된다.
protected: 자식 클래스에서 접근 가능하나 인스턴스에서는 사용할 수 없다.
- 추상 클래스
추상 클래스는 new로 인스턴스를 생성할 수 없고 오직 상속만 가능하다.
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 {
constrcutor(color: string) {
super(color);
}
doSomthing(){
alert(3);
}
}
const z4 = new Bmw("black");
추상 클래스의 메서드를 추상화한다는 것은 상속받은 자식 클래스들이 모두 동일한 이름의 메서드를 가지고 있지만 내부 로직은 독자적이라는 것을 의미한다. 따라서 추상 클래스 내의 추상 메서드는 이름만 선언하고, 자식 클래스에서는 해당 메서드에 대한 로직을 꼭 적어주어야 한다.
- 제네릭
interface User {
name: string;
age: number;
}
interface Car {
name: string;
color: string;
}
interface Book {
price: number;
}
const user: User = {name: "a", age: 10};
const car: Car = {name: "bmw", age: "red"};
const book: Book = {price: 3000};
function showName<T extends { name: string }>(data: T): string {
return data.name;
}
showName(user);
showName(car);
showName(book); //에러
<T extends { name: string }>의 의미는 T는 {name: string}의 확장된 형태라는 것. 즉 다양한 객체가 들어올 수 있어도 그 객체는 무조건 타입이 string인 name 프로퍼티를 가진 객체여야 한다는 의미이다. 따라서 book 에는 ame객체가 없기 때문에 showName(book)을 했을 때 에러가 나게 된다.
- Partical<T>
: T의 내용을 옵셔널로 갖는다.
interface User {
id: number;
name: string;
age: number;
gender: "m" | "f";
}
let admin: Partical<User> = {
id: 1,
name: "Bob"
}
위의 코드는
interface User {
id?: number;
name?: string;
age?: number;
gender?: "m" | "f";
}
이렇게 사용하는 것과 같다. 그래서 여기 없는 프로퍼티를 사용하려고 하면 에러가 난다.
- Required<T>
Partical 과 반대로 모든 프로퍼티가 사용되어야 한다.
interface User {
id: number;
name: string;
age?: number;
}
let admin: Required<User> = {
id: 1,
name: "Bob",
age: 30
}
이렇게 interface에서 age가 옵셔널이어도 Required로 사용하면 필수 프로퍼티가 된다.
- Readonly<T>
: 이후의 수정이 불가능해진다.
interface User {
id: number;
name: string;
age?: number;
}
let admin: Readonly<User> = {
id: 1,
name: "Bob",
}
admin.id = 4; //에러
이렇게 Readonly이기 때문에 이후에 수정하는 것이 불가능하다.
- Record<K, T>
K는 key이고 T는 Type으로 key에는 K에 해당하는 것이 포함되고 타입은 T에 해당하는 것에 포함되면 된다.
interface Score {
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
"1": |"A"|"B"|"C"|"D";
}
const scor: Score = {
1: "A",
2: "C",
3: "B",
4: "D"
}
이렇게 작성되어 있는 것을 Record를 사용하면 반복을 조금 줄일 수 있다.
type Grade = "1"|"2"|"3"|"4";
type Score = "A"|"B"|"C"|"D";
const score: Record<Grade, Score> = {
1: "A",
2: "C",
3: "B",
4: "D"
}
Grade를 key로 Score를 Type으로 사용하는 것이다.
- NonNullable<Type>
null을 제외한 타입을 사용하는 것
type T1 = string | null | undefined | void;
type T2 = NonNullable<T>;
이런 경우 T2는 string 혹은 void만 타입으로 가지게 된다.
'일상 > Today I Learned' 카테고리의 다른 글
2023.02.01 (0) | 2023.02.01 |
---|---|
2023.01.31 (0) | 2023.01.31 |
[데브코스 Day53] 2022.12.28 (0) | 2022.12.28 |
[데브코스 Day52] 2022.12.27 (0) | 2022.12.27 |
[데브코스 Day51] 2022.12.26 (0) | 2022.12.26 |