根据同级键的值推断对象键的类型

时间:2020-01-20 17:50:36

标签: typescript

我有一个带有两个键的对象类型Options

  1. strategy:需要一个未知类型的参数的函数
  2. parameter:与strategy的第一个参数的类型相同

我希望能够执行以下操作

type FooParameter = { foo: string }
type BarParameter = { bar: string }

const fooOptions: Options = {
  strategy: (parameter: FooParameter) => {},
  parameter: { foo: 'foo' }
}
const barOptions: Options = {
  strategy: (parameter: BarParameter) => {},
  parameter: { bar: 'bar' }
}

应从fooOptions.parameter推断类型fooOptions.strategy,并从barOptions.parameter推断barOptions.strategy

今天使用TypeScript可以吗?

1 个答案:

答案 0 :(得分:0)

我能想到的唯一方法是使用泛型。我认为没有解决方案,编译器将在不使用泛型的情况下检查parameter是否是strategy的合适参数。

type Options<T> = {
    strategy: (parameter: T) => void,
    parameter: T
}

这意味着如果在类型注释中使用Options,则必须提供一个类型参数:

const fooOptions: Options<FooParameter> = {
    strategy: (parameter: FooParameter) => {},
    parameter: { foo: 'foo' }
}

function useOptions<T>(o: Options<T>): void {
    o.strategy(o.parameter);
}

但是,在允许编译器推断类型的任何地方(即,无论何时不使用类型注释),都不必为泛型类型参数提供显式类型。特别是,诸如useOptions函数之类的API的用户可以传递对象文字,并享受类型检查和类型推断的好处:

useOptions({
    strategy: param => {
        let x = param.x; // Inferred as number
        let y = param.y; // Inferred as string

        // Error: Property 'z' does not exist on type '{ x: number, y: string }'
        let z = param.z;
    },
    parameter: { x: 1, y: 'foo' }
});

请注意,此示例中的用户不必显式编写{ x: number, y: string }或等效类型即可使用API​​。

Playground Link