TypeScript条件类型:从React组件中提取组件属性类型

42

使用TypeScript 2.8的新条件泛型类型功能,能否提取React.ComponentType<TProps>组件的TProps?我想要一个类型, 可以同时适用于ComponentTypeTProps本身,所以您可以作为开发人员传递其中的任何一个:

例如:

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

这是否可能,并且有人能够提供解决方案吗?


可能是Typescript React: 访问组件属性类型的重复问题。 - Mišo
3个回答

119

不错的发现,Sebastien。 - Joseph King
这是方法。 - Honest Charley Bodkin

10

我建议使用React.ComponentType,因为它也包括函数组件:

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

现在将您的答案标记为正确的,因为我也支持 React 16.8 中引入的基于函数/钩子的组件。 - Dynalon
为什么返回TComponentOrTProps,如果它没有继承自React.ComponentType? - Cristian E.

5
这是关于条件类型及其推理行为(使用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

这个在 React 16.8 中引入的函数组件(类型为 React.FC<TProps>)中已经不再起作用了。 - Dynalon
为什么返回TComponentOrTProps,如果它没有继承自React.ComponentType? - Cristian E.
@CristianE。我认为这是必要的,以使ExtractProps<TestProps>正常工作。如果将ExtractProps与React.Component一起使用,则会从其声明中提取props。否则,ExtractProps将假定TComponentOrTProps只是一个Props接口,并将其原样返回。 - SleepWalker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接