我认为你能做的最接近的是输入someFunction 并使用函数重载。 Options 让它有点复杂,但这样的事情应该可以工作:
type MyFunc<T extends MyType | string> = () => T;
interface Options<T extends MyType | string> {
someMapping: WhateverTypeThisIs;
someFunc: MyFunc<T>;
}
function getValue(options: Options<MyType>): MyType;
function getValue(options: Options<string>): string;
function getValue<T extends MyType | string>(options: Options<T>): T {
return options.someFunc();
}
所以现在你应该得到这样的类型:
const myTypeOptions: Options<MyType> = {
someMapping: {},
someFunc: () => ({ myParam: "MyValue" })
};
const myStringOptions: Options<string> = {
someMapping: {},
someFunc: () => "Hello"
};
const myTypeValue = getValue(myOptions); // myNumberValue is of type { myParam: string };
const myStringValue = getValue(myStringOptions); // myStringValue is a string;
这当然取决于所讨论的函数总是返回MyType或总是返回string这一事实。如果它根据函数的参数而变化,那么它将始终是MyType | string,因为 Typescript 无法确定这一点。由调用者来弄清楚它是什么。
编辑:
根据您提供的场景,这样的事情可能会有所帮助。您可以创建MyFunc 的类型。
type MyTypeFunc = (myType: MyType) => MyType;
type MyStringFunc = (myType: MyType) => string;
interface MyOptions {
someMapping: WatheverTypeThisIs;
}
interface MyTypeOptions extends MyOptions {
someFunc: MyTypeFunc;
}
interface MyStringOptions extends MyOptions {
someFunc: MyStringFunc;
}
function getValue(options: MyTypeOptions): MyType;
function getValue(options: MyStringOptions): string;
function getValue(options: MyTypeOptions | MyStringOptions): T {
return options.someFunc();
}
现在,无论何时调用它,您都可以创建如下选项:
const myTypeOptions: MyTypeOptions = {
someMapping: {},
someFunc: (myType) => myType
}
const myStringOptions: MyStringOptions = {
someMapping: {},
someFunc: (myType) => myType.someProperty
}
const myTypeValue = getValue(myTypeOptions); // myTypeValue will be of type MyType
const myStringValue = getValue(myStringOptions); // myStringValue will be of type string