не может удовлетворить тип возвращаемого значения для типизированной функции машинописи - PullRequest
0 голосов
/ 30 апреля 2018

Скажите, у меня есть этот тип:

  export type Transformer = <T extends any[], U>(
    data: T,
  ) => U;

Затем у меня есть эта функция, которую я хочу соответствовать этому типу:

export const transform: Transformer = (
  data: Result[]
): { data:Result[] } => {
  if (!data) {
    return { data: [] };
  }


  data.forEach((record:Result) => {
    record.extraStuff = {
      foo: 'bar'
    };
  });

  return { data: data };
};

Компилятор жалуется:

Type '(data: Result[]) => { data: RecordMatchingSearchResult[]; }' is not assignable to type 'Transformer'.
  Type '{ data: Result[]; }' is not assignable to type 'U'.

Нужно ли добавить общее ограничение для U, чтобы сделать его вывод.

Я также не писал тип, но немного странно, что он не принимает универсальные аргументы, но вместо этого они существуют в функции.

1 Ответ

0 голосов
/ 30 апреля 2018

Проблема с вашей функцией в том, что она не является действительно общей. У вас есть сигнатура универсальной функции (Transformer), и вы пытаетесь назначить функцию, которая не является универсальной.

Проблема возникает с типом возвращаемого значения, в частности, потому что вызывающий должен указать тип возвращаемого значения, поэтому вызывающий будет ожидать, что указанный им тип возвращаемого значения не будет вашим неуниверсальным результатом ({ data: Result[] }). Если ваше назначение было разрешено, этот вызов вызовет ошибку времени выполнения:

let result = transform<Result[], { other: number }>([]);
result.other // this would cause an error 

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

export type Transformer = <T extends { extraStuff: any }>(
    data: T[],
) => { data: T[] };

class Result {
    extraStuff: any;
}
export const transform: Transformer = <T extends { extraStuff: any }>(data: T[]): { data: T[] } => {
    if (!data) {
        return { data: [] };
    }


    data.forEach((record: T) => {
        record.extraStuff = {
            foo: 'bar'
        };
    });

    return { data: data };
};

Или вы можете переместить обобщенные значения Transfomer из сигнатуры функции в тип и указать аргументы типа при объявлении функции transform, поэтому сами функции не должны быть универсальными:

export type Transformer<T extends { extraStuff: any }, U> = (
    data: T[],
) => U;

export const transform: Transformer<Result, { data: Result[] }> = (data: Result[]): { data: Result[] } => {
    if (!data) {
        return { data: [] };
    }


    data.forEach((record: T) => {
        record.extraStuff = {
            foo: 'bar'
        };
    });

    return { data: data };
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...