https://blog.jez.io/intro-elim/
Every type is defined by its intro and elim forms
- Intro forms: 타입의 인스턴스를 어떻게 “생성”하는지 정의.
- Elim forms: 생성된 타입 인스턴스를 어떻게 “사용”하거나 “해체”할지 정의.
타입을 정의할 때, 생성과 사용의 명확한 경계를 설정해서 Intro/Elim 설계를 명시적으로 표현하기
class Rectangle {
private constructor(public width: number, public height: number) {}
static create(width: number, height: number) {
if (width <= 0 || height <= 0) {
return null
}
return new Rectangle(width, height)
}
getArea() {
return this.width * this.height
}
}
const rect = Rectangle.create(10, 20)
if (rect) {
console.log(rect.getArea())
}
Types are not their elim forms
interface
와class
를 통해 Intro/Elim 모두를 명시적으로 정의- 팩토리 메서드 같은 패턴을 활용해 생성 방식을 추상화
interface Shape {
getArea(): number
}
class Circle implements Shape {
constructor(private radius: number) {}
getArea() {
return Math.PI * this.radius ** 2
}
}
class Rectangle implements Shape {
constructor(private width: number, private height: number) {}
getArea() {
return this.width * this.height
}
}
function createShape(type: 'circle' | 'rectangle', ...args: number[]) {
if (type === 'circle' && args.length === 1) {
return new Circle(args[0])
}
if (type === 'rectangle' && args.length === 2) {
return new Rectangle(args[0], args[1])
}
return null
}
const shape = createShape('circle', 10)
if (shape) {
console.log(shape.getArea())
}