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.