Возможно ли присвоить возвращаемое значение функции типу generic?

#typescript

#typescript

Вопрос:

Я пытаюсь присвоить логический результат функции универсальному типу. Возможно ли это? У меня есть следующая схема:

 interface FormalWebFieldProps {
  name: string
  id: string
  onChange: (e: FormalTextFieldEvent) => void
}

interface FormalNativeFieldProps {
  onChangeText: (text: string) => void
}

type FormalFieldProps<IsNative> = {
  disabled: boolean
  value: any
  error?: string
} amp; (IsNative extends true ? FormalNativeFieldProps : FormalWebFieldProps)
  

Если я просто передам <true> or <false> в универсальный тип FormalFieldProps , это сработает:

 const getWebFieldProps = (): FormalFieldProps<false> => {
  return {
    id: 'field id',
    name: 'field name',
    disabled: false,
    value: 'foo',
    error: 'error',
    onChange: e => console.log(e.target.value)
  }
}

const getNativeFieldProps = (): FormalFieldProps<true> => {
  return {
    disabled: false,
    value: 'foo',
    error: 'error',
    onChangeText: text => console.log(text)
  }
}
  

Однако, поскольку эта проверка является динамической и выполняется во время выполнения, я не знаю, возможно ли присвоить возвращаемое значение этой функции универсальному типу, что-то вроде этого:

 const isNative = () => false

const getDynamicFieldProps = (): FormalFieldProps<bool = isNative()> => {
  const extra = !isNative() ? {
    id: 'field id',
    name: 'field name',
    onChange: e => console.log(e.target.value)
  } : {
    onChangeText: text => console.log(text)
  }

  return {
    disabled: false,
    value: 'foo',
    error: 'error',
    ...extra
  }
}
  

Комментарии:

1. TypeScript выполняет проверку типа только во время компиляции. Он может определять типы возвращаемых значений только из типов, а не значений

2. @Richard да, я предполагаю, что это может произойти. Любое предлагаемое решение?

3. Тип объединения, подобный const getDynamicFieldProps = (): FormalFieldProps<boolean> => ... , у вас не работает? Я думаю, мне нужно увидеть больше вариантов использования здесь, прежде чем я смогу предложить какое-либо другое решение.

Ответ №1:

попробуйте объявить свой флаг как обычное объявление, например, isNegative = false;

и с помощью тернарного оператора вы можете выполнить свой блок кода

Нравится

 isNegative? {
    id: 'field id',
    name: 'field name',
    disabled: false,
    value: 'foo',
    error: 'error',
    onChange: e => console.log(e.target.value)
  }: {
    disabled: false,
    value: 'foo',
    error: 'error',
    onChangeText: text => console.log(text)
  }
  

это не идеальный код, но вы получите некоторое представление.

Комментарии:

1. Но это нарушит мой ввод.