У меня есть такая функция:

export const getValue = (
  options: Options = { someMapping, someFunction }
): string | MyType => {
  ...
  return someFunction({ ...someData });
};

Прямо сейчас тип возвращаемого значения - строка или MyType.

Это потому, что someFunction может возвращать либо строку, либо MyType.

Есть ли способ использовать условный тип TypeScript для возврата правильного типа на основе того, что фактически возвращает someFunction?

[Дополнительная информация после первого сообщения] .

Вот определение типа параметров:

export interface Options {
  someMapping: MappingType;
  someFunc: (data: MyType) => MyType | string;
}

Параметр someFunc - это функция, которая ожидает параметр MyType.

Вот две фактические функции, которые я передаю в зависимости от ситуации:

const myFunc = (data: MyType): string => {
  return data.someProperty;
};

const myFunc = (data: MyType): MyType => {
  return data;
};
0
techguy2000 11 Апр 2019 в 21:38

2 ответа

Лучший ответ

Я думаю, что самое близкое, что вы можете сделать, это набрать 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
1
DeeV 11 Апр 2019 в 20:58

детская площадка вы можете позволить машинописи выводить тип возвращаемого значения. Перегрузка функций, предоставляемая @DeeV, также работает.

0
Pavel Kratochvil 11 Апр 2019 в 19:08