【问题标题】:Check types in argument of generic function and return object literal type of this argument检查泛型函数参数中的类型并返回此参数的对象字面量类型
【发布时间】:2020-06-13 16:06:01
【问题描述】:

我的任务

我有两个接口。

interface ComponentOptions<Props> {
  abstract?: boolean;
  functional: boolean;
  props?: Props;
  name?: string;
  render?(props: Props): boolean;
}

interface ComponentProps {
  title: string;
  dark: boolean;
}

我需要实现一个功能

  • 采用接口替换Props 泛型类型
  • 是否对函数参数对象中的 Props 类型进行任何检查
  • 根据传递的参数对象返回一个对象字面量类型
    • 不返回ComponentOptions&lt;Props&gt;接口

strict: true 需要编译器选项。

实际解决方案

我已经实现了createComponent 函数,它接收两个参数:

  • 必需的options 对象字面量
  • props,被视为类型转换的假想参数
function createComponent<
  Props,
  Options extends ComponentOptions<Props>
>(options: Options, props: Props): Options {
  props;
  return options;
}

通过这样的实现,我达到了预期的结果。但我不是很喜欢。

const component = createComponent({
  abstract: true,
  functional: true
}, {})

const componentWithProps = createComponent({
  functional: false,
  name: 'bar',
  props: {
    title: 'bar',
    dark: true
  },
  render(props) {
    return props.dark
  }
}, {} as ComponentProps)

问题

我想摆脱 props 参数只留下 options,并使用通用参数设置道具的类型,而不是强制转换 props 参数。

它可能看起来像这样:

const component = createComponent<ComponentProps>({
  functional: true,
  props: { // Check 'title' and 'dark' types
    title: 'comp',
    dark: true
  },
  render(props) { // Pass type for the props
    return props.dark;
  }
})

// When we hover on `component` variable,
// display all defined properties in the `options`
{
  functional: true,
  props: ComponentProps,
  render(props: ComponentProps): boolean
}

如何做到这一点?

Link to Playground

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    我用这个解决方案解决了我的问题:

    interface FunctionalComponent<Props> {
      <Options extends ComponentOptions<Props>>(opts: Options): Options
    }
    
    function createFunctionalComponent<Props = {}>() {
      return (o => o) as FunctionalComponent<Props>;
    }
    
    const component3 = createFunctionalComponent<ComponentProps>()({
      functional: false,
      name: 'bar',
      props: {
        title: 'bar',
        dark: true
      },
      render(props) {
        return props.dark
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-26
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多