TypeScript: общий тип интерфейса с одним обязательным полем

Я хочу создать функцию f, которая принимает строку и создает объект, где key - единственный набор полей.

Я также хочу, чтобы функция проверила тип интерфейса A, чтобы убедиться, что поле key является единственным обязательным полем объекта. (Будут другие необязательные поля).

Проблема:

Можно ли выразить тип A так, чтобы функция f была действительной - и не вызывала ошибки типа - и все же правильно проверяла A типы при использовании?

export function f<A extends { key: string }>(key: string): A {
  return { key }; // This produces compile error TS2322: (see below)
}

// This be a few different interfaces, but they all have in common that
// the key-field is the only required field.
interface WithKey {
  key: string;
  ignoreMe?: string;
}

const result = f<WithKey>('myKey');

Ошибка компилятора:

TS2322: Введите '{ключ: строка; } 'не может быть назначен типу' A '. '{ключ: строка; } 'назначается ограничению типа' A ', но' A 'может быть создан с другим подтипом ограничения' {key: string; } '.


person tomaj    schedule 12.05.2020    source источник


Ответы (1)


Проблема в том, что ваш оператор говорит, что он принимает тип, который должен иметь key из string, и этот тип будет возвращен.

это означает, что если я пройду туда

{key: 1, requiredField: 5}

он возвращает тот же тип, что и у меня requiredField.

Но реализация return { key } нарушает этот оператор, потому что он больше не возвращает requiredField. Это вызывает TS2322.

Возможное решение - просто скажите интерфейс, который вы возвращаете.

export function f(key: string): { key: string } { // <- return type
  return { key };
}

interface WithKey {
  key: string;
  ignoreMe?: string;
}

const result: WithKey = f('myKey');

result.key; // works
result.ignoreMe // works (undefined)
person satanTime    schedule 12.05.2020
comment
Отличный ответ, который направил меня на правильный путь. Я слишком много думал об этом. :) Спасибо @satanTime! - person tomaj; 13.05.2020
comment
Вот код, который я получил в своем проекте: github.com/ItemConsulting/enonic-fp/blob/ - person tomaj; 13.05.2020