在下面的示例中,我按预期的那样工作了,我的问题是-是否仍然可以重写它,这样我就不必同时通过通用的SyncManager
和T
道具。理想情况下,我只想传递as
prop并让组件的prop接口使用它。
在TypeScript中可以吗?
as
答案 0 :(得分:0)
实现第二种变体非常容易,即需要显式类型参数的变体:
解决方案之一
import * as React from 'react';
type Props<K extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[K];
declare class MyComponent<K extends keyof JSX.IntrinsicElements> extends React.Component<Props<K>> {}
<MyComponent<'a'> href="https://example.com/" id="myLink" />;
解决方案二
当涉及第一个变体时,则比较棘手。您想要的不是通用组件,而是道具的结合。为了说明原因,让我们考虑一个具体示例,其中MyComponent
仅处理a
和button
的并集。
import * as React from 'react';
type Props =
| ({ as: 'a' } & JSX.IntrinsicElements['a'])
| ({ as: 'button' } & JSX.IntrinsicElements['button']);
declare class MyComponent<T extends 'a' | 'button'> extends React.Component<Props> {}
<MyComponent as="a" href="https://example.com" />; // ✔ OK
<MyComponent as="button" href="https://example.com" />; // ✘ Compile-time error
MyComponent
不必泛泛即可识别其应接收的道具。 as
道具是足够的判别。
我们可以通过创建所有标签及其相应道具的并集来概括该示例:
import * as React from 'react';
type Props = {
[K in keyof JSX.IntrinsicElements]: { as: K } & JSX.IntrinsicElements[K];
}[keyof JSX.IntrinsicElements];
declare class MyComponent extends React.Component<Props> {}
<MyComponent as="a" href="https://example.com" />; // ✔ OK
<MyComponent as="button" href="https://example.com" />; // ✘ Compile-time error
这将完成工作,就像我们手动定义联合一样。但是,创建如此庞大的联盟存在弊端:
需要注意的一点! ;)