구조적 타이핑의 특성 때문에 가끔 코드가 의도하지 않은 결과를 낼 수 있습니다.
아래의 예제가 바로 그러한 상황을 표현하고 있습니다.
|
interface Vector2D {
x: number;
y: number;
};
function clacNorm(p: Vector2D){
return Math.sqrt(p.x * p.x + p.y * p.y);
}
clacNorm({x: 3, y: 4}); // 정상 결과 5
const vec3D = {x : 3, y: 4, z: 1};
clacNorm(vec3D); // 정상 결과 5
// 구조적 타이핑 관점에서는 이상이 없는 것이지만 수학적 결과를 기대했다면 오류이다.
|
clacNorm 함수가 3차원 벡터를 허용하지 않게 하려면 공식 명칭(nominal typing)을 사용하면 됩니다. 공식 명칭 개념을 타입스크립트에서 묘사 하려면 '상표(brand)'를 붙히면 됩니다.
|
interface Vector2D {
_brand: '2d';
x: number;
y: number;
};
function vec2D(x: number, y: number): Vector2D {
return {x, y, _brand: '2d'};
}
function calcNorm(p: Vector2D) {
return Math.sqrt(p.x * p.x + p.y * p.y);
}
calcNorm(vec2D(3, 4));
const vec3D = { x: 3, y: 4, z: 1};
calcNorm(vec3D); // 비정상 _brand 속성 없음.
|
|
type ABSPath = string & {_brand : 'abs'};
function listAbsPath(path: ABSPath) {
console.log(path);
}
function isAbsPath(path: string): path is ABSPath {
return path.startsWith('/');
}
function f(path: string){
if(isAbsPath(path)){
listAbsPath(path); // 정상
}
listAbsPath(path); // 비정상
}
|
타입스크립트는 구조적 타이핑을 사용하기 때문에, 값을 세밀하게 구분하지 못하는 경우가 있다. 값을 구별하기 위해 공식 명칭이 필요하다면 상표를 붙이는 것을 고려해야한다.
상표 기법은 타입 시스템에서 동작하지만, 런타임에 상표를 검사하는 것과 동일한 효과를 얻을 수 있다.
'IT' 카테고리의 다른 글
| Effective Typescript - 39 - any를 구체적으로 변형해서 사용하기 (0) | 2022.01.24 |
|---|---|
| Effective Typescript - 38 - any 타입은 가능한 좁은 범위에서만 사용하기 (0) | 2022.01.24 |
| Effective Typescript - 36 - 해당 분야의 용어로 타입 이름 짓기 (0) | 2022.01.23 |
| Effective Typescript - 35 - 데이터가 아닌, API와 명세를 보고 타입 만들기 (0) | 2022.01.23 |
| Effective Typescript - 34 - 부정확한 타입보다는 미완성 타입을 사용하기 (0) | 2022.01.23 |