Skip to content

Commit

Permalink
2024-07-22
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuni-Q committed Jul 22, 2024
1 parent e77f0f9 commit b1f2bab
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,90 @@ sendEmail(st);
- 추상 메서드를 가지는 대신 객체를 직접 만들 수 없는 클래스를 추상 클래스라 부른다.
- 추상 클래스를 만드는 목적은 언제나 메서드의 존재에 관한 정보를 타입 검사기에 제공하려는 것이다.
- 언어가 구조에 의한 서브타입을 제공한다면 추상 메서드의 필요성이 다소 줄어든다.

## 2.2 집합론적 타입

### 최대 타입

- '아무 값이나 가능하다'는 타입
- 모든 값을 포함하는 타입
- 모든 타입은 최대 타입에 속한다.
- 모든 타입은 최대 타입의 서브타입이다.
- 최대 타입의 부품은 만들기 쉽다. 그런 만큼 최대 타입의 부품은 아무 값이나 결과로 낼 수 있기에 결과로 나온 값이 어떤 능력을 가지는지 모른다. 그래서 최대 타입의 부품은 조심스럽게, 별다른 특별한 능력을 요구하지 않는 곳에만 사용해야 한다.
- 타입스크립트에서 최대타입은 any가 아니라 unknown이다.

### 최소 타입

- '계산을 끝마치지 못한다'를 표현하는 타입
- 속하는 값이 존재하지 않는다.
- 최소 타입은 모든 타입의 서브타입이다.
- 최소 타입은 아무렇게나 어느 곳에든 사용할 수 있다. 대신 최소 타입의 부품은 만들기 어렵다. 예외를 발생시키거나 재귀 호출을 하는 등의 특별한 방법으로만 최소 타입의 부품을 만들 수 있다.
- 타입스크립트의 최소 타입의 이름은 never다.

### 이거나 타입

- 이거나 타입 은두개의 타입으로부터 만들어진다. 타입 A와 B로 만든 이거나 타입은 `A | B`라 쓰며 직관적으로 'A이거나 B'를 나타낸다.
- 위치에 민감한 타입 검사가 잘 작동하도록 프로그램의 구조를 단순하게 만들어야 한다.

```ts
function write(data: string | number): void {
if (typeof data === 'string') {
let str: string = data;
} else {
let num: number = data;
}
}
```

### 이면서 타입

- 타입 A와 B로 만든 이면서 타입은 `A & B`라 쓰며 직관적으로 'A이면서 B'를 나타낸다. 즉, 어떤값이 A에도 속하고 B에도 속해야지만 `A & B`에 속한다.
- 이면서 타입은 다중상속이 있을 때 유용하다.``

## 2.3 함수와 서브타입

- 함수의 타입은 매개변수 타입과 결과 타입으로 구성된다.
- A가 B의 서브타입 일 때 C => A가 C => B의 서브타입이다. 즉, 함수 타입은 결과 타입의 서브타입 관계를 유지 한다.
- A가 B의 서브타입일 때 B => C가 A => C의 서브타입이다. 그 반대는 성립하지 않는다. 함수 타입은 매개변수 타입의 서브타입 관계를 뒤집는다.

```ts
class Person {
email: string;
}
class Student {
email: string;
grad: number;
}
function startMentoring(select: (s: Student) => Person): void {
let st: Student = new Student();
let mentor: Person = select(st);
}
function selectStudentMentor(st: Student): Student {}
function sendEmails(needEmail: (s: Student) => Boolean): void {
let st: Student = new Student();
if (needEmail(st)) {
}
}
function isHacked(pr: Person): Boolean {}
sendEmails(isHacked);
```

## 타입 검사기의 서브타입 관계 판단 규칙

- 객체타입
- 이름에 의한 서브타입을 시용하는 경우: 클래스 A가 B를 상속하면 A는 B의 서브타입이다.
- 구조에 의한 서브타입을 사용하는 경우 A가 B에 있는 필드와 메서드를 모두 가지고 있으면 A는 B의 서브타입이다.
- 최대타입
- 모든타입은 최대 타입의 서브타입이다.
- 최소타입
- 최소 타입은 모든 타입의 서브타입이다.
- 이거나타입
- A와 B는 A|B의 서브타입이다.
- 이면서 타입
- C가 A의 서브타입이면서 B의 서브타입이면 C는 A&B의 서브타입이다.
- 함수타입
- A가 B의 서브타입이고 C가 D의 서브타입이면 B => C는 A => D의 서브타입이다.

---

[[번역] 집합론으로 이해하는 타입스크립트 thumbs up](https://itchallenger.tistory.com/874)
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: 3장 매개변수에 의한 다형성
date: 2024-07-21 13:07:50
category: 타입으로 견고하게 다형성으로 유연하게
tags: []
draft: true
---

## 3.1 제네릭 함수

- 한 개 이상의 타입 매개변수를 가지는 함수를 제네릭 함수(generic function)라고 부른다.
- 대부분의 언어에서는 제네릭 함수 정의를 검사 할 때 타입 매개변수가 아무 타입이나 나타낼 수 있다고 가정한다.
- 매개변수에 의한 다형성을 제공하는 대부분의 언어는 타입 인자 추론을 함께 제공한다.
- 타입 인자 추론이 언제나 내가 원하는 대로 되지는 않는다는 사실을 항상 기억해야 한다. 타입 검사기가 내 프로그램을 거부한 이유를 잘 모르겠을 때는 생략한 타입 인자를 하나씩 다시 넣어 보는 것이 도움이 될 수 있다.
- 제네릭 함수를 정의할 때도 타입 추론을 하는 방식 중 하나가 `힌들리-밀너 타입 추론`이다.
- 타입 매개 변수를 쓰지 않아도 함수가 자동으로 제네릭 함수가 될 수 있다는 말이다.
- 어떤 매개변수가 함수 안에서 특별한 능력 이 요구되지 않는 곳에서만 사용된 다면 그 매개변수의 타입은 타입 매개변수를 사용해 표현할 수 있다. 따라서 그런 매개변수가 하나라도 발견된다변 그 함수는 제네릭 함수가 된다.
- 힌들리 밀너 타입 추론 대신 `렛 다형성`이라는 용어를 사용하는 데, 이는 힌툴리-밀너 타입 추론을 사용하는 대표적인 언어인 오캐멀에서 함수를 정의할 때 사용하는 키워드가 let인 데서 온 것이다.

## 3.2 제네릭 타입

- 타입에 타입 매개변수를 추가하면 제네릭 타입이 된다.
- 자료 구조의 타입이 대개 제네릭 타입이다.

## 3.3 무엇이든 타입

- 제네릭 메서드를 대신 사용 할 수 있다고해서 무엇이든 타입의 가치가 사라지는 것은 아니다.
- 제네릭 메서드를 가진 객체를 인자로 넘기기보다는 제네릭 함수를 바로 인자로 넘기는 편이 더 간결하다. 이를 가능케하는 무엇이든 타입이 요긴한 이유다.
- 자바의 일급 함수와 비슷한 케이스이다.

```ts
// function simulate(){
// const int = randUniform([1,2,3]);
// const str = randUniform(["1", "2", "3"]);

// return int || str
// }

function simulate<T>(rand: (arr: T[]) => T): void {
// Type 'number' is not assignable to type 'T'.
// 'T' could be instantiated with an arbitrary type which could be unrelated to 'number'
const int = rand([1, 2, 3]);
// Type 'number' is not assignable to type 'T'.
// 'T' could be instantiated with an arbitrary type which could be unrelated to 'number'
const str = rand(['1', '2', '3']);
}

function randUniform<T>(arr: T[]): T {
return arr[0];
}
function randGeometric<T>(arr: T[]): T {
return arr[0];
}

const i = simulate(randUniform);
console.log(i);
const s = simulate(randGeometric);
console.log(s);

// function simulate<T>(arr: T[], rand: (arr: T[]) => T): T {
// return rand(arr);
// }

// const i = simulate([1,2,3], randUniform);
// console.log(i);
// const s = simulate(["1", "2", "3"], randGeometric);
// console.log(s);
```

- 무엇이든 타입은 최소 타입과 비슷하다. 아무 값도 최소 타입에 속하지 않듯이 무엇이든 타입의 값을 만드는 것은 어려운 편이다. 인자가 무슨 타입 인지 모르기 때문에 인자를 가지고 할수 있는 일이 제한적이다. 인자를 그대로 반환하거나 인자를 출력하는 일 정도가 고작이다.
- 무엇이든 타입에 속하는값 은 얼마 없다. 그 대신 무엇이든 타입을 사용하기는 매우 쉽다. 최소 타입의 부품을 아무 데나 넣을 수 있는 것과 비슷하다.
- 무엇이든 할 수 있는 사람은 찾기 어렵다. 무슨 일을 맡기든 척척 잘 해낼 것 이다.

## 3.4 무엇인가 타입

- 무엇인가 타입은 `존재 양화 타입`이라고 번역할 수도 있다.
- 일반적으로 정적 타입 언어가 제공하는 기능들은 더 많은 프로그램이 문제없이 타입 검사를 통과할 수 있도록 돕는다. 반면 무엇인가 타입의 역할은 정반대다. 오히려 타입 검사를 통과할 수 있는 프로그램 이 타입 검사를 통과하지 못하도록 방해한다. 이는 보통 필요 없는 능력이다. 하지만 라이브러리를 만드는 입장에서는 라이브러리 사용자의 행동을 제약할 필요가 있다.
- 무엇인가 타입은 최대 타입과 비슷하다. 아무 값이나 최대 타입의 값이 될 수 있듯이 무엇인가 타입의 값을 만드는 것 역시 쉽다. 또, 최대타입의 값을 사용 할 수 있는 곳이 거의 없는 것처럼, 무엇인가 타입의 값을 사용하는 방법 또한 제한적이다.
- 무엇인가 할 수 있는 사람은 찾기 쉽다. 누구나 각자 자신이 잘하는 일이 있 다. 무엇인가 할 수 있는 사람에게는 그 사람이 잘할 수 있는 일을 찾아 줘야 한다. 아무거나 시켜서는 그 사람의 능력을 다 발휘하기 어렵다.

```ts
interface Timestamper<T = unknown> {
init(): T;
next(t: T): T;
cmp(t1: T, t2: T): boolean;
}

class IntTimestamper implements Timestamper<number> {
init(): number {
return 0;
}
next(t: number): number {
return t + 1;
}
cmp(t1: number, t2: number): boolean {
return t1 < t2;
}
}

class StringTimestamper implements Timestamper<string> {
init(): string {
return 'a';
}
next(t: string): string {
return t + 'a';
}
cmp(t1: string, t2: string): boolean {
return t1.length < t2.length;
}
}

function create(): Timestamper<number | string> {
if (Math.random() < 0.5) {
return new IntTimestamper();
} else {
return new StringTimestamper();
}
}

const t: Timestamper = create();
const ts0 = t.init();
const tsl = t.next(ts0);
const bol = t.cmp(ts0, tsl);
```
29 changes: 28 additions & 1 deletion src/components/about/workExperiences/Woowa.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,33 @@ export const Woowa = () => {
<TBody>
<Tr>
<Th>period</Th>
<Td>24.02 ~ Current</Td>
<Td>24.05 ~ </Td>
</Tr>
<Tr>
<Th>position</Th>
<Td>FrontEnd/BackEnd Engineer/Product Manager</Td>
</Tr>
</TBody>
</Table>
<Ul>
<Li>우아한웤플로 구성원 모집(기획2, 디자인1, 서버2, 프론트10)</Li>
<Li>사내 프로덕트 합병(우아한북마크)</Li>
<Li>업무 요청 프로세스 개선</Li>
<Ul>
<Li>서포트 앱 만들기</Li>
<Li>서포트 가이드 제공</Li>
<Li>이모지로 자동화 기능 제공</Li>
</Ul>
</Ul>
</Section>
{/* */}
<Section>
<H3>배민공통서비스웹프론트개발팀</H3>
<Table>
<TBody>
<Tr>
<Th>period</Th>
<Td>24.02 ~ 24.05</Td>
</Tr>
<Tr>
<Th>position</Th>
Expand Down Expand Up @@ -150,6 +176,7 @@ export const Woowa = () => {
</Ul>
</Ul>
</Section>
{/* */}
<Section>
<H3>주문/결제 파트</H3>
<Table>
Expand Down

0 comments on commit b1f2bab

Please sign in to comment.