Написание интерфейса для типа или функции, возвращающей тип - PullRequest
1 голос
/ 13 июля 2020

У меня есть объект, содержащий некоторую конфигурацию по умолчанию. Некоторые из его значений не могут быть определены статически и должны быть рассчитаны во время выполнения. Чтобы применить эти значения по умолчанию к объекту, я буду применять любые c значения, а также выполнять и применять возврат любых функций.

const SETTINGS = {
  prop1: true,
  prop2: (config: Config): boolean => config.prop2,
  prop3: (config: Config): number => config.prop2,
  prop4: 0,
} as DefaultSettings

Написать интерфейс для этого объекта сложно. Любое данное свойство может быть либо значением stati c, либо функцией, возвращающей значение. Я хочу, чтобы интерфейс мог представлять несколько объектов такого типа, где имена свойств и типы свойств совпадают, но любое свойство может быть либо значением, либо функцией.

interface DefaultSettings {
  prop1: boolean
  prop2: boolean
  prop3: number
  prop4: number
}

Интерфейс выше предполагает, что все свойства являются значениями stati c, что неверно.

Как мне ввести значение, которое может быть или не быть функцией?

1 Ответ

2 голосов
/ 13 июля 2020

Чтобы свойство имело два (или более) разных типа, вы можете использовать оператор объединения

interface DefaultSettings {
  prop1: boolean | ((config: Config) => boolean);
  prop2: boolean | ((config: Config) => boolean);
  prop3: number;
  prop4: number;
}

Чтобы не повторяться, вы также можете создать тип для этого :

type ConfigBoolean = boolean | ((config: Config) => boolean);

interface DefaultSettings {
  prop1: ConfigBoolean;
  prop2: ConfigBoolean;
  prop3: number;
  prop4: number;
}

Вы можете даже go дальше, используя дженерики. Если, например, number также может быть либо примитивом, либо функцией, возвращающей этот примитив:

type ConfigType<T> = T | ((config: Config) => T);

interface DefaultSettings {
 prop1: ConfigType<boolean>;
 prop2: ConfigType<boolean>;
 prop3: ConfigType<number>;
 prop4: ConfigType<number>;
}

Скобки вокруг типа функции необходимы, иначе компилятор думает: boolean | (config: Config) и запутывается после этого :). Если вы перевернете его: (config: Config) => boolean | boolean, он все равно будет неоднозначным. В этом случае компилятор будет думать, что тип - это функция, которая возвращает логическое или логическое значение, так что это тоже нечетно

...