TypeScript 条件类型:从 react 组件中提取组件 props 类型

IT技术 reactjs typescript types conditional-types
2021-04-28 17:20:18

使用typescript2.8新的条件一般类型的特点,就是它可以提取TProps一个的React.ComponentType<TProps>组成部分?我想要一个类型,可无论是在工作ComponentType还是在TProps自身,这样你就可以-作为一名开发人员-通过这两个之一:

例如:

interface TestProps {
    foo: string;
}

const TestComponent extends React.Component<TestProps, {}> {
    render() { return null; }
}

// now I need to create a type using conditional types so that
// I can pass either the component or the props and always get the 
// TProps type back
type ExtractProps<TComponentOrTProps> = /* ?? how to do it? */

type a = ExtractProps<TestComponent> // type a should be TestProps
type b = ExtractProps<TestProps>     // type b should also be TestProps

这是可能的,任何人都可以提供解决方案吗?

3个回答

有一个内置的帮助程序

type AnyCompProps = React.ComponentProps<typeof AnyComp>

它也适用于原生 DOM 元素:

type DivProps = React.ComponentProps<"div">

https://stackoverflow.com/a/55005902/82609

我建议使用React.ComponentType,因为它还将包括功能组件:

type ExtractProps<TComponentOrTProps> =
  TComponentOrTProps extends React.ComponentType<infer TProps>
    ? TProps
    : TComponentOrTProps;

这是条件类型及其推理行为的非常直接的应用(使用infer关键字)

interface TestProps {
    foo: string;
}

class TestComponent extends React.Component<TestProps, {}> {
    render() { return null; }
}

type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends React.Component<infer TProps, any> ? TProps : TComponentOrTProps;

type a = ExtractProps<TestComponent> // type a is TestProps
type b = ExtractProps<TestProps>     // type b is TestProps