为 returns 类型的类型或函数编写接口

Writing an interface for type, or function that returns type

我有一个包含一些默认配置的对象。它的一些值不能静态定义,需要在运行时计算。要将这些默认值应用于对象,我将应用任何静态值,并执行和应用任何函数的 return。

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

为此对象编写接口很困难。任何给定的 属性 都可以是 静态值或 return 值的函数。我希望接口能够表示多个此类对象,其中 属性 名称和 属性 类型相同,但任何 属性 都可以是值或函数。

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

以上接口假定所有属性都是静态值,这是不正确的。

如何键入可能是函数也可能不是函数的值?

要使 属性 具有两种(或更多)不同类型,您可以使用 union operator

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;
}

您甚至可以通过使用泛型走得更远。例如,如果 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,它仍然是模棱两可的。在这种情况下,编译器会认为该类型是一个 returns 布尔值或布尔值的函数,所以这也很奇怪