2016-10-07 4 views
0

В этом конкретном примере, я расширяя интерфейс Array<T> следующим образом:Перезапись/метод коррекции подписи в интерфейсе машинописи

interface BetterArray<T> extends Array<T> { 
    push(this: BetterArray<T>, value: T): this; 
} 

Примечание для справки - Array<T>.push реализуется как этот

interface Array<T> { 
    push(...items: T[]): number; 
} 

Но я получаю следующую ошибку во время компиляции:

Interface 'BetterArray' incorrectly extends interface 'T[]'.
Types of property 'push' are incompatible. Type '(this: BetterArray, value: T) => this' is not assignable to type '(...items: T[]) => number'. Type 'this' is not assignable to type 'number'. Type 'BetterArray' is not assignable to type 'number'.

Есть ли способ, которым я могу принудительно проинструктировать TypeScript, что я хочу перезаписать нажимаю на мой интерфейс (например, member hiding in C#)?

Примечание - Я использую машинопись 2.0

Дальнейшее чтение - оказывается, что это чисто вниз, чтобы вернуться типа - в основном я хочу, чтобы обеспечить соблюдение интерфейсом, новый тип возврата ...

interface A { 
    fn(): number; 
} 

interface B extends A { 
    fn(): this; 
} 

Interface 'B' incorrectly extends interface 'A'. Types of property 'fn' are incompatible. Type '() => this' is not assignable to type '() => number'. Type 'this' is not assignable to type 'number'. Type 'B' is not assignable to type 'number'.

ответ

1

Вам просто нужно добавить оригинальную подпись Array.push:

interface BetterArray<T> extends Array<T> { 
    push(...items: T[]): number; 
    push(this: BetterArray<T>, value: T): this; 
} 

Проблема с тем, что вы хотите сделать, хотя в том, что если this является BetterArray, то вы не можете вернуться this для exampl:

class BetterArrayClass<T> extends Array<T> { 
    push(...items: T[]): number; 
    push(this: BetterArrayClass<T>, value: T): this; 
    push(this: BetterArrayClass<T>, ...items: T[]): number | this { 
     return this; 
    } 
} 

Ошибки с:

Type 'BetterArrayClass' is not assignable to type 'number | this'.
Type 'BetterArrayClass' is not assignable to type 'this'.
this: BetterArrayClass

Причина для этого можно увидеть в этом простом примере:

class A { 
    fn(this: A, num: number): this { 
     return this; // Error: Type 'A' is not assignable to type 'this'. this: A 
    } 
} 

class B extends A { 
    fn(num: number): this { 
     if (num < 0) { 
      return super.fn(num); 
     } 
     return this; 
    } 
} 

Если в B.fn мы звоним super.fn, тогда this не A, а B, и в любом случае мы хотим вернуть экземпляр B.
Это не то, что описывает A.fn.

+0

Большое спасибо за это, однако, это немного сложнее, когда дело доходит до даже не используя классы, и нужно немного углубиться в JS, потому что TypeScript просто не способен испускать конструкцию, которую я строю. В связи с этим я нашел другое решение, основанное на вашем.См. Мое решение. – series0ne

+0

. Интересно, что это за конструкция вашего, что машинопись не справляется с –

+0

Ну, для этого нужен конструктор, который может это сделать: new (n ?: T): T & Q .. . и TypeScript плачет, как ребенок, когда я пытался сделать это с помощью класса! – series0ne

0

Согласно nitzan tomer's | answer

Вам просто нужно добавить оригинальную подпись Array.push:

interface BetterArray<T> extends Array<T> { 
    push(...items: T[]): number; 
    push(this: BetterArray<T>, value: T): this; 
} 

Использование never типа, кажется, работает для этого. Intellisense улавливает, что never, «Никогда не» возвращается, так что не мешает показывать вам сигнатуру метода (неразбавленный)

interface BetterArray<T> extends Array<T> { 
    push(...items: T[]): never; 
    push(this: BetterArray<T>, value: T): this; 
} 
+0

Странно ... но кажется, что он удаляет метод «никогда» без первого нажатия (...) в цепочке. – series0ne

+0

Хотя использование 'never' дает вам этот желаемый эффект intellisense, это неправильное использование этой функции и может стать причиной неприятностей в будущем, поскольку она« лежит »о фактической реализации. –

+0

@ NitzanTomer не могу просто интерпретировать это как «эта реализация будет« НИКОГДА »не произойдет»? -cheeky emoji- – series0ne

Смежные вопросы