Итак, я пишу бэкэнд, который полагается на DynamoDB, и в рамках этого я пишу простой набор функций поверх пакета SDK для узлов, чтобы упростить тестирование кода. Если одна из этих функций возвращает данные, я хотел бы иметь возможность присваивать значение типизированным объектам, не возвращая any или не выполняя приведение типов. Я пробовал такой общий параметр:

export const getAll = async<T extends Record<string, unknown>[]> (
  table: string
): Promise<T> => {
  const params = {
    TableName: table,
  };
  const result = await dynamoDb.scan(params).promise();
  return result.Items ?? [];
};

Когда я пытаюсь скомпилировать это, я получаю следующее сообщение об ошибке

Тип "ItemList" нельзя присвоить типу "T". 'T' может быть создан с другим подтипом ограничения 'Record '

Теперь я думаю, что понимаю, почему это не работает, потому что при написании функции невозможно узнать, что такое T, поэтому невозможно гарантировать, что будет связь между тем, что функция фактически возвращает, и параметром типа. .

Я пробовал вводить его как тип record:

type Customer = {
   id: string;
   name: string;
}

export const getAll = async (
  table: string
): Promise<Record<string, unknown>[]>> => {
  const params = {
    TableName: table,
  };
  const result = await dynamoDb.scan(params).promise();
  return result.Items ?? [];
};

Но теперь, когда я пытаюсь назначить его переменной типа Customer, я получаю следующее сообщение об ошибке:

Тип «Record []» не может быть назначен типу «Customer»: для типа «Record » отсутствуют следующие свойства типа «Customer»: id, name

В настоящее время я делаю последнее, но мне нужно сделать довольно неприятное приведение as unknown as Customer[], чтобы заставить его работать. Я уверен, что это неверно, поэтому я бы очень признателен за совет о том, как правильно набрать это.

0
Ben Wainwright 8 Дек 2020 в 13:48

1 ответ

Лучший ответ

Если вам не нужна какая-либо проверка типов во время выполнения, вам, вероятно, лучше всего просто привести тип возвращаемого значения из DynamoDB как T[], используя что-то вроде этого:

import { DynamoDB } from "aws-sdk";
const dynamoDb = new DynamoDB.DocumentClient();

type Customer = {
  id: string;
  name: string;
};

export const getAll = async <T>(table: string): Promise<T[]> => {
  const params = { TableName: table };
  const result = await dynamoDb.scan(params).promise();
  return result.Items as T[] ?? [];
};

const doIt = async () => {
  const customers: Customer[] = await getAll<Customer>("my-customer-id");
  // Do something with your customers
};
0
paulyb 9 Дек 2020 в 08:23