9

Specмашинопись Array.prototype.map декларация

Согласно MDN specification for Array.prototype.map() карте должны быть использованы, как это ...

var new_array = arr.map(callback[, thisArg]) 

Проблема

Машинопись имеет несколько перегруженных деклараций для карты, и это очень затрудняет extend Array<T>.

я ожидал бы увидеть эту (который находится в lib.d.ts) ...

map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; 

Но lib.d.ts также имеет эти ...

map<U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U]; 

map<U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U]; 

map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U]; 

map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U]; 

Возражение

Поскольку JavaScript не разрешает перегрузку метода, а также не использует TypeScript для реализации класса, я не что TypeScript должен допускать это для эмбиентных объявлений.

Вопросы

  1. Почему машинопись позволяет перегруженных подписей для окружающей среды деклараций?
  2. Как переопределить реализацию карты в классе, который расширяет массив?

Я поднял это на GitHub тоже ... https://github.com/Microsoft/TypeScript/issues/13785

Примечание

ReadonlyArray<T> имеет только одну сигнатуру для карты, которая ...

map<U>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => U, thisArg?: any): U[]; 
+0

Интересно, что вы не спрашивали о том, что ИМО будет самым важным аспектом здесь: _purpose_. Как в * «зачем определять все эти сигнатуры перегрузки в первую очередь?» * - И ответом на это будет тот факт, что TypeScript имеет тип-концепцию массивов с конечным количеством элементов, например '[number , number, number] 'является 3-элементным номером []'. Это присваивается как _to_, так и _from_ 'number []', но не является _precisely_ одинаковым с точки зрения компилятора. Кроме того, они также называются типами кортежей в некотором контексте и могут определять необязательно связанные между собой типы elem. –

+0

@JohnWeisz Я получаю эту концепцию n-элементов массивов, но тогда почему эта концепция в этом отношении останавливается на 5-элементных массивах? Неужели n может быть бесконечным? – series0ne

ответ

2

(1) Если не разрешено перегружать подписи в эмбиентных объявлениях, как бы вы получили различную подпись s в собственных js-функциях/методах?
В lib.d.ts много перегрузок, которые отражают работу собственных js-объектов.

(2) Вам необходимо сообщить компилятору, что вы покрываете все возможные объявленные подписи.
В вашем случае вы можете сделать что-то вроде:

class A<T> extends Array<T> { 
    map<U>(this: Array<U>, ...args: any[]); 
    map<U>(this: Array<T>, callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] { 
     return []; 
    } 
} 

Первая подпись перегрузки заботится о тех, которые вы не хотите возиться с.

1

Ваш вопрос затрагивает различные аспекты TypeScript. Я обработаю их индивидуально, а потом все вместе.

Массив <T>

интерфейсы служат двойной цели в машинописном:

  1. Они позволяют создавать «истинные» интерфейсы для других (пока не существующих) классов для реализации. Когда вы его реализуете, вы должны внедрить его, потому что интерфейс обеспечивает гарантию доступности всех его членов.
  2. Они позволяют вам определить интерфейс уже существующий тип javascript. Это очень полезно, если вы хотите использовать одну из многих существующих библиотек и по-прежнему иметь преимущества статической типизации. Эти интерфейсы обычно определяются в файле .d.ts (и файл lib.d.ts содержит основные типы JavaScript). Эти интерфейсы адаптированы к существующему типу, и они обычно не предназначены для реализации. Вы можете, хотя, если хотите, но вы должны реализовать всех своих членов.

Интерфейс Array<T> имеет второй тип и, как таковой, он не предназначен для вас.

this Параметры в функции

this: параметра в определении функции не является реальным параметр в том смысле, что вы можете передать аргументы. Он позволяет указать, какой тип вы ожидаете от значения this в теле функции. Если вы не указали это, this будет иметь тип any, что часто не очень полезно.

Функция/Метод Перегрузки

В машинопись, функции и методы не перегружены в том смысле, что они перегружены в языках, как Java или C#. Вы не можете реализовать его чаще, чем один раз, но вы можете определить альтернативные подписи, чтобы разрешить статическую типизацию для функций, возвращающих типы вариантов, или использовать параметры варианта. Особенно в файлах определения .d.ts это полезно и часто необходимо, поскольку существующие библиотеки используют слабый набор JavaScript для возврата значений или ожидают параметры разных типов. Это делает ваше возражение ложным. Для этих конструкций JavaScript необходима перегрузка функций.

Кортеж

В массиве JavaScript можно присваивать значения разных типов в каждом из слотов. В определении массива TypeScript вы указываете один тип, который обеспечивает соблюдение. Чтобы заполнить пробел, вы можете определить кортежи. Тип типа [number, string, string] переводится в массив JavaScript any[], и TypeScript все еще может применять статическую типизацию.

Суммарный метод

Массив перегружает вы возражаете против в Array<T> ввести статически типизированных this параметр в случае, если массив является актуальной [T, T], [T, T, T], [T, T, T, T], [T, T, T, T, T].Это не означает, что массив предоставляет несколько методов map. Это тот же метод, но перегружен для определенных типов массивов. Он представлен в lib.d.ts и, как таковой, не был разработан вами. Вы можете расширить базовый класс (который уже существует даже без интерфейса), но перегрузки вам не повредит (по крайней мере, не в этом случае, поскольку они предоставляют только параметры this).

+1

'Array' на самом деле является классом, который вы можете расширить, что-то, что вы должны были проверить перед отправкой этого ответа. Все ваши длительные объяснения, вероятно, известны OP (в зависимости от того, о чем он спрашивал и как он его просил). –

+0

@NitzanTomer: Я проверил (https://github.com/Microsoft/TypeScript/blob/master/lib/lib.d.ts - поиск по «интерфейсу Array {"), и вы, кажется, знаете OP лучше, чем Я делаю. – Sefe

+0

Вы также увидите, что после 'interface Array ' есть 'интерфейс ArrayConstructor', который определяет конструкторы, а затем' declare const Array: ArrayConstructor', который делает класс Array. –

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

  • Нет связанных вопросов^_^