Подпись машинописного текста для рекурсивной функции выравнивания

#recursion #typescript

#рекурсия #машинописный текст

Вопрос:

Я работаю над созданием файла Typescript .ds для reactive-coffee (http://yang.github.io/reactive-coffee/api.html ), и я сталкиваюсь с проблемами, пытаясь определить подпись типа для flatten функции. Пример:

 flatten(rx.array([1, [2, 3], rx.cell(4), rx.array([rx.cell([5, rx.cell(6)])])])) 
// -> [1,2,3,4,5,6]
flatten([1, [2, 3], rx.cell(4), rx.array([rx.cell([5, rx.cell(6)])])]) 
// -> [1,2,3,4,5,6]
  

Вопрос, с которым я столкнулся, заключается в следующем: какова правильная подпись типа Typescript для xs? Пока я придумал что-то вроде этого:

 interface NestableCell<T> extends ObsCellInterface<T | NestableCell<T>> {}

type Flattenable<T> = (
    Array<T| NestableCell<T | Flattenable<T>> | Flattenable<T>> |
    ObsArrayInterface<T | NestableCell<T | Flattenable<T>> | Flattenable<T>>
)

function flatten<T>(xs:Flattenable<T>) => ObsArrayInterface<T>
  

ObsCellInterface и ObsArrayInterface являются типизированными версиями объектов RC ObsCell и ObsArray соответственно.

К сожалению, Typescript не допускает рекурсивных типов, только рекурсивные интерфейсы. И на данный момент я действительно не уверен, как преобразовать этот тип в интерфейс.

Ответ №1:

Кажется, что следующее работает, хотя у меня еще не было времени доказать, что оно удовлетворяет всем возможным случаям:

 interface NestableCell<T> extends ObsCell<T | NestableCell<T>> {}

interface FlattenableRX<T> extends ObsArray<
    T |
    NestableCell<T | FlattenableJS<T> | FlattenableRX<T>> |
    FlattenableJS<T> |
    FlattenableRX<T>
> {}

interface FlattenableJS<T> extends Array<
    T |
    NestableCell<T | FlattenableJS<T> | FlattenableRX<T>> |
    FlattenableJS<T> |
    FlattenableRX<T>
> {}

export type Flattenable<T> = FlattenableRX<T> | FlattenableJS<T>
  

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

Как я уже сказал, я пока не могу доказать, что это работает, но это, по крайней мере, кажется правдоподобным.