728x90
📍 23일 차 11.25. 목(실시간 강의)
오늘은 interface
, generic
문법에 대해서 배웠다.
❏ Interface
- 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용 가능
- 직접 인스턴스를 생성할 수 없음. 모든 메서드는 추상 메서드다. (이때
abstract
키워드를 사용하지 않는다) - 선언만 존재한다. (JS로 변환되면 인터페이서는 사라진다.)
interface
간에extends
를 사용하여 다중 상속 가능(class와 비슷)- 추상 클래스와 다른 점: 추상
class
는 전체적인 구조,interface
는 프로그래머 간의 협업 개발을 할 때 사용 - 함수의 매개변수(파라미터로)로 사용
API
응답에서 데이터의 구조를 결정할 때 사용
// 키 값을 다음처럼 정해주면 키 값은 제한이 없다.
interface User {
[grade: number]: "A" | "B" | "C" | "D"
}
let user: User = {
1: "A",
2: "B",
5: "D",
}
- 선택적 프로퍼티(?):
?
가 붙는 경우는 반드시 구현되지 않고 선택 가능
// 키 값을 다음처럼 정해주면 키 값은 제한이 없다.
interface User {
1: string;
2?: string;
5: string
}
let user: User = {
1: "A",
5: "D",
}
- 클래스 선언문의
implements
를 붙여서 사용 가능(인터페이스를 구현하는 클래스의 일관성을 유지할 수 있는 장점을 가짐)
// 모든 메소드는 추상 메소드여야 한다.
// 인터페이스에서 정의한 타입은 클래스 안에서도 모두 적용해야한다.
interface ITodo {
id: number;
content: string;
completed: boolean;
sayHello(): void;
}
class Todo implements ITodo {
constructor(
public id: number,
public content: string,
public completed: boolean
){}
sayHello(){
console.log(`안녕하세요!!`)
}
}
const today = new Todo(1, "TED", true); // 인스턴스
console.log(today) // Todo { id: 1, content: 'TED', completed: true }
today.sayHello(); // 안녕하세요!!
- 함수와 변수에서도 덕타입이 적용된다.(덕 타이핑: 타입 체크에서 중요한 것은 값을 실제 가지고 있느냐에 관한 것, 인터페이스에서 정의한 프로퍼티나 메서드를 가지고 있다면 그 인터페이스를 구현한 것으로 여김 덕 타이핑 또는 구조적 타이핑이라 부름)
type IPerson = {
name: string
}
function sayHello(person: IPerson): void{
console.log(`Hello ${person.name}`)
}
const me = {name : "TED", age: 27};
sayHello(me);
❏ 디자인패턴
- 생성패턴: 객체를 생성하는데 관련한 패턴
- 구조패턴: 프로그램의 구조에 관련한 패턴
- 행위패턴: 반복적으로 사용되는 객체들의 상호작용 패턴
// 전략 패턴
interface Weapon {
attack: () => void;
}
class Sword implements Weapon {
public attack() {
console.log("검 공격");
}
}
class Spear implements Weapon {
public attack() {
console.log("창 공격");
}
}
class Bow implements Weapon {
public attack() {
console.log("활 공격");
}
}
class GameUser {
private weapon: Weapon | null = null;
public setWeapon(weapon: Weapon) {
this.weapon = weapon;
}
public attack() {
if (this.weapon === null) {
console.log("맨손 공격");
} else {
this.weapon.attack();
}
}
}
const testUser = new GameUser();
testUser.setWeapon(new Spear());
testUser.attack(); // 창
testUser.setWeapon(new Bow());
testUser.attack(); // 활 공격
testUser.setWeapon(new Sword());
testUser.attack(); // 검 공격
testUser.setWeapon(null);
testUser.attack(); // 맨손 공격
728x90
❏ 제네릭(Generic)
- 데이터 타입을 일반화함
- 자료형을 정하지 않고 여러 타입을 사용할 수 있게 한다.(범용적인 함수를 쓰고 싶을 때?, 여러 가지 타입을 사용하고 싶을 때)
- 재사용성이 높은 함수를 만들어줄 때 사용됨
- 한 가지 타입보다 여러 가지 타입에서 동작하는 함수를 생성한다.
// class 문법에서의 제네릭
class Stack<T> {
private data: T[] = [];
constructor(){}
push(item: T): void {
this.data.push(item);
}
pop():T | undefined{
return this.data.pop()
}
}
// 인스턴스의 타입을 유연하게 설정할 수 있다.
const numberStack = new Stack<number>();
const stringStack = new Stack<string>();
numberStack.push(1);
stringStack.push('a')
// 함수에서의 제네릭
function getSize<T>(arr: T[]): number {
return arr.length;
}
const arr1 = [1, 2, 3];
getSize<number>(arr1);
const arr2 = ['a', 'b', 'c'];
getSize<string>(arr2);
- 제네릭 한 변수를 추가하고 싶을 때
<T, U>
// 1
function toPair<T, U>(a: T, b: U): [T, U]{
return [a, b];
}
toPair<number, string>(1, "1");
toPair<string, boolean>("Hello", true);
// 2
function logText<T>(text: T[]): number{
return text.length;
}
// 3
interface Mobile<T>{
name: string;
price: number;
option: T;
}
let myInfo: Mobile<boolean> = {
name: "TED",
price: 6000,
option: true
}
let yourInfo: Mobile<object> = {
name: "TED",
price: 6000,
option: {
age: 28,
color: "orange",
}
}
// 함수에서의 제네릭
// <T>는 text의 인자는 T로 받고 리턴값도 T 타입으로 해준다.
interface GenericLogTextFn {
<T>(text: T): T;
}
interface GenericLogTextFn<T> {
(text: T): T
}
function logText<T>(text: T): T{
return text;
}
let myString: GenericLogTextFn<string> = logText;
console.log(myString)
interface Mobile<T> {
name: string;
price: number;
option: T;
}
interface OptionType {
color: string;
coupon: boolean;
}
const m1: Mobile<OptionType> = {
name: "s21",
price: 1000,
option: { color: "red", coupon: false },
};
// 제네릭 상속
interface User {
name: string;
age: number;
}
interface Book {
price: number;
}
let user: User = { name: "a", age : 10 };
let book: Book = { price: 3000 };
function showName<T extends { name : string }>(data: T){
return data.name;
}
❏ Non-null assertion operator
Null
이 아닌 어선별 연산자는 피연산자가null
이 아니라고 컴파일러에게 전달하여 일시적으로Null
제약조건을 완화합니다. 권장하지 않는 문법이고 대신&&
을 사용한다.
❏ Union type
// example1
function getAge(age: number | string){
return typeof age === "number" ? age.toFixed() : age;
}
const myAge = getAge(28);
console.log(myAge)
const yourAge = getAge("25");
console.log(yourAge)
// union 기호
interface Person {
name: string;
age: number;
}
interface Developer {
name: string;
skill: string;
}
// 겹치는 속성만 사용 가능
function introduce(someone: Person | Developer){
someone.name;
someone.age; // Error
someone.skill; // Error
}
// 모든 속성 사용 가능
function introduce(someone: Person & Developer){
someone.name;
someone.age; // 사용 가능
someone.skill; // 사용 가능
}
❏ 제약 조건(constraints / keyof)
- 제네릭 타입에 어느 정도 힌트를 주고 제약을 걸기 위해 사용, 최소한
length
속성이 있어야 에러가 나지 않는다
interface LengthWise {
length: number;
}
interface Rect {
length: number;
area: number;
}
function logText1<T extends LengthWise | Rect>(text: T){
console.log(text.length);
console.log(text.area); // 공통되는 속성이 아니므로 Error가 난다.
}
function logText1<T extends LengthWise & Rect>(text: T){
console.log(text.length);
console.log(text.area); // 모든 속성 사용 가능하므로 Error가 나지 않는다.
❏ keyof를 사용한 제약
- 객체의 속성을 제약하고 싶을 때 사용
// 객체 안에서의 속성만 사용하는 문법
function getProperty<T, O extends keyof T>(obj: T, key: O){
return obj[key]
}
let obj = { a: 1, b: 2, c: 3 }
// 'a' | 'b' | 'c'
console.log(getProperty(obj, 'c'));
❏ 기타 기능 및 개념
- Type Assertion: 타입 추론기능은 강력하지만 한계 존재, 타입단언(type assertion)은 타입스크립트가 추정하지 못하는 부분까지 개발자가 선언하는 것
- as
let a;
a = 10;
a = 'abc';
let b = a;
b = a as string;
interface Person{
name: string;
age: number;
}
interface Developer{
name: string;
skill: string;
}
function introduce(someone: Person | Developer){
someone.name;
(someone as Person).age;
(someone as Developer).skill;
}
- typeGuard
// 함수
function doSomeThing(id: string | number){
if (typeof id === 'string'){
console.log(id.trim());
}else {
console.log(id);
}
}
// 클래스
class Diner {}
class Merchant {}
function doSomething(user: Diner | Merchant){
if(user instanceof Diner){
}else{
}
}
// 메소드
interface Bird {
fly(): string;
}
interface Fish {
swim(): number;
}
function doSomething(animal: Fish | Bird){
if('swim' in animal){
console.log((animal as Fish).swim())
}else{
console.log((animal as Bird).fly())
}
}
doSomething({
swim: () => {
return 82
}
})
doSomething({
fly: () => {
return "Hello"
}
})
// 타입 확인
function isFish(animal: Fish | Bird): animal is Fish {
return (animal as Fish).swim !== undefined;
}
function doSomething(animal: Fish | Bird){
if (isFish(animal)) {
animal.swim()
}else{
animal.fly()
}
}
❏ 실습
- 클래스 vs 추상클래스: 어떤 메서드는 그냥 구현해도 되고, 어떤 메서드는 정의되지 않은 메서드 일 수 있다.(사용하려면 상속이 필요하다)
- 인터페이스: 추상클래스와 달리
abstract
를 사용하지 않음. 구성되는 것의 타입만 명시해서(생성자나 메서드 구현을 작성할 필요가 없다.) (하나의 interface에 여러 데이터가 뭉치지 않도록 분산시킬 수 있기 때문에 다중 상속이 가능하다.) interface
vstype
vsabstract
// 인터페이스: 상속이 가능하며, 다중 상속도 가능하다. 내부에서 메서드 구현을 할 수 없다.
interface Test {
name: string;
id: number;
introduce(): void;
}
// 상속이 불가능하다. 내부에서 메서드 구현을 할 수 없다.
type Test {
name: string;
id: number;
introduce(): void;
}
// 클래스이기 대문에 상속은 가능하지만, 다중 상속은 불가하다. 원하는 메서드는 구현을 할 수 있다.
abstract class Test {
name: string;
id: number;
abstractintroduce(): void;
}
T extends number | string
: 2개 이상 상속이 가능함.interface
활용 예시: 데이터베이스 조작(로그인, 게시물, 등등)- ORM: SQL문을 대신해서 내가 알고 있는 프로그래밍 언어로 DB로 조작하는 방법(나중에 SQL문으로 변환된다)
❏ Generic
- 선언한 시점에 타입을 사용하는 것이 아니라 사용할 때 모든 타입을 마음대로 넣을 수 있다.
- 타입에 제한을 걸기 위해
<T extends string | number>
처럼 사용할 수 있다.
❏ 자바스크립트의 동적인 타입 예시
true == "true"
:false
abstract equality composition (피연산자에number
씌우고 비교한다)010-03=5
, 0 붙어서 8진수가 된다. (16진수는 ox, 2진수는 ob)1+'1' = '11'
(+
는 문자열 우선순위),11-'1' = 10
(-
는Number
만 지원한다.)0/0=NaN
, 숫자로 취급하지 않는다.1 / 0 > 10 * 1000 = true
: True, infinity는 표현 범위를 넘어서면 취급한다true++=>Error
: 값에다가 붙이는 게 아니라 변수에다 선언해야 한다.1+2+"3" = 33
반응형
'Frontend > 엘리스 SW 엔지니어 트랙' 카테고리의 다른 글
[ 엘리스 SW 엔지니어 트랙 ] 25일차 (0) | 2021.11.28 |
---|---|
[ 엘리스 SW 엔지니어 트랙 ] 24일차 (0) | 2021.11.26 |
[ 엘리스 SW 엔지니어 트랙 ] 22일차 (0) | 2021.11.24 |
[ 엘리스 SW 엔지니어 트랙 ] 21일차(5주차: 클린코드와 타입스크립트 - 정적타입, 인터페이스, Generic, Decorator) (0) | 2021.11.23 |
[ 엘리스 SW 엔지니어 트랙 ] 20일차 (0) | 2021.11.21 |
댓글