본문으로 바로가기
interface Point2D {
  norminal: Point2D;
  x: number;
  y: number;
}

interface Point3D {
  norminal: Point3D;
  x: number;
  y: number;
  z: number;
}

type Nominal<T> = T;

const point2D = <Nominal<Point2D>> { x: 16, y: 24 };
const point3D = <Nominal<Point3D>> { x: 39, y: 7, z: 12 };

interface DisableDuckTyping<T extends Point2D> extends Point2D {  readonly norminal: T;  }
  
type p2dType = DisableDuckTyping<Point2D>;
type p3dType = DisableDuckTyping<Point3D>;

const p2d = (1 as never as p2dType);
const p3d = (2 as never as p3dType); 

// then

function iTakePoint2D(point: p3dType) { 
    console.log(point.x, point.y);
}

iTakePoint2D(point2D); // error: iTakePoint2D parameter type mismatch
iTakePoint2D(point3D); // point type is p3dType, so it works.