2016-05-20 3 views
1

Я вижу противоречивую информацию об этом. https://basarat.gitbooks.io/typescript/content/docs/classes.html (перейти в раздел наследства) здесь говорит, что это поддерживается, но я вижу, мой код не в состоянии собрать в машинописном playGroundПоддерживает ли TypeScript ducktype?

class Point{ 
    x:number; 
    y:number; 
    constructor(x:number, y:number){ 
    this.x = x; 
    this.y = y ;  
    } 

    add(point:Point){ 
    return new Point(this.x + point.x , this.y + point.y); 
    } 
} 

class Point3D extends Point{ 
    z:number; 
    constructor(x:number, y:number, z:number){ 
     super(x,y); 
     this.z = z; 
    } 

    add(point3d:Point3D){ 
     // Error does not support duct type. 
     var point2D = super.add({point3d.x, point3d.y}); 
     return new Point3D(point2D.x, point2D.y, this.z); 
    } 
} 
+0

машинопись на самом деле не утка набран, увидеть мой обновленный ответ. – Alex

ответ

3

Не будет в вашем случае достаточно хорошо, чтобы просто передать экземпляр Point как:

add(point3d:Point3D){ 
    // Error does not support duct type. 
    //var point2D = super.add({point3d.x, point3d.y}); 

    var point2D = super.add(point3d); 

Потому что супер просто принимает точку

add(point:Point){... 

и Point3d является точка

class Point3D extends Point{ 

updated playground

В случае, мы хотели бы использовать утку набрав в полной силе, мы должны ввести интерфейс

interface IPoint{ 
    x:number; 
    y:number; 
} 

и потреблять, что в способе добавления

add(point:IPoint){ 
return new Point(this.x + point.x , this.y + point.y); 
} 

и, наконец, мы можем использовать утку набрав:

var point2D = super.add({x: point3d.x, y: point3d.y}); 

Скорректированный example is here

2

машинопись на самом деле не duck typed, а structurally typed. Разница в основном заключается в том, что утка-типизация только заботится о том, что конкретные члены, к которым вы обращаетесь во время выполнения, есть, в то время как структурная типизация требует от вас выполнить весь договор на объект, который вы хотите действовать как конкретный интерфейс/тип ,

При отправке в объект {x:point3d.x, y:point3d.y} TypeScript требует, чтобы этот объект был структурно совместим с Point, что не так, поскольку он не имеет add-method.

1

Вы пытаетесь создать объект {x:number, y:number} и назовите его точкой. Однако точка имеет тип {x:number, y:number, add:(point:Point)=>Point}. Если вы введете свойство «добавить», которое соответствует этой сигнатуре, оно будет работать.

1

Здесь есть пара вещей.

  1. Ваш синтаксис неверен. {point3d.x, point3d.y} должно быть {x: point.x, y: point.y}, если вы пытаетесь создать объект.
  2. В этом случае вы не можете использовать ducktype, потому что ваш объект не имеет метода add (компилятор скажет вам об этом). Ниже я создал интерфейс под названием IPoint, чтобы удовлетворить компилятор.

Смотрите мое решение:

interface IPoint { 
    x: number; 
    y: number; 
} 

class Point{ 
    x:number; 
    y:number; 
    constructor(x:number, y:number){ 
    this.x = x; 
    this.y = y ;  
    } 

    add(point:IPoint){ 
    return new Point(this.x + point.x , this.y + point.y); 
    } 
} 

class Point3D extends Point{ 
    z:number; 
    constructor(x:number, y:number, z:number){ 
     super(x,y); 
     this.z = z; 
    } 

    add(point:Point3D){ 
     var point2D = super.add({x: point.x, y: point.y}); 
     return new Point3D(point2D.x, point2D.y, this.z); 
    } 
} 
Смежные вопросы