我正在开发一个组件库,该库在组件的分组方式上有一些变化。我将组件分组为类,以便最终用户更轻松地使用该库。他们不会记住哪些名为
slots
可用,而是使用点符号访问自定义插槽。例如,Card
组件可以具有 Header
、Body
和 Footer
。在我的图书馆中,我想像这样使用这些组件:
<Card>
<Card.Header>I am a Header</Card.Header>
<Card.Body>I am a Body</Card.Body>
<Card.Footer>I am a Footer</Card.Footer>
</Card>
我目前正在使用此功能,但我也在尝试将其强类型化,这就是我遇到麻烦的地方。这是我的文件结构:
card
| Card.svelte
| Body.svelte
| Header.svelte
| Footer.svelte
| index.ts
我的index.ts文件有以下代码:
import OriginalCard from './Card.svelte';
import Header from './Header.svelte';
import Footer from './Footer.svelte';
import Body from './Body.svelte';
const Card = OriginalCard;
Card.Header = Header;
Card.Body = Body;
Card.Footer = Footer;
export default Card;
页眉、正文和页脚均返回以下错误:
Property 'Header' does not exist on type 'typeof default'. ts(2339)
像这样使用组件时:
<script lang="ts>
import Card from '@components/card';
</script>
<Card>
<Card.Header>I am a Header</Card.Header>
<Card.Body>I am a Body</Card.Body>
<Card.Footer>I am a Footer</Card.Footer>
</Card>
页眉、正文和页脚均返回以下错误:
Property 'Body' does not exist on type 'typeof Card__SvelteComponent_'. ts(2339)
如何修复这些错误?
编辑
在另一个项目中安装此软件包后,我注意到接受的答案无法解决的两个问题:
1)。
<Card />
返回以下 ts 错误 - 预期 0 个参数,但得到 1。并破坏了允许属性的所有智能感知。
2)。智能感知不适用于点表示法。当输入
<Card.
时,我没有得到任何子组件的建议,而只是显示整个包中的所有组件。
期望的结果是没有 ts 错误并且不会丢失包的智能感知。
我还尝试像这样扩展
CardStatic
:
interface CardStatic extends OriginalCard
并且同样的问题继续存在。
您必须扩展已知类型才能添加其他属性。由于它们是静态的,我会尝试这样的事情:
const Card = OriginalCard as CardStatic;
Card.Header = Header;
Card.Body = Body;
Card.Footer = Footer;
export default Card;
export interface CardStatic {
new(...args: ConstructorParameters<typeof OriginalCard>): OriginalCard;
Header: typeof Header;
Body: typeof Body;
Footer: typeof Footer;
}
当用于创建组件库时,我在 SvelteKit 中找到了一种更简单的方法:从 lib 文件夹的
index.ts
文件中导出名为 Card 的对象,如下所示:
import _Card from "./Card.svelte";
import _CardBody from "./CardBody.svelte";
import _CardHeader from "./CardHeader.svelte";
import _CardFooter from "./CardFooter.svelte";
export const Card = {
Root: _Card,
Footer: _CardFooter,
Header: _CardHeader,
Body: _CardBody
};
有了这个,您不需要额外的输入,但有一个问题:
<Card>
组件现在是<Card.Root>
。它将从其他项目导入和使用,如下所示:
<script lang="ts">
import { Card } from 'the-component-library';
</script>
<Card.Root>
<Card.Header>My Header</Card.Header>
<Card.Footer>My Footer</Card.Footer>
</Card.Root>
由于这个问题,我想说这不能被视为答案,但我仍然自愿,以防这个问题对人们来说是一件小事,而不是通过接受的答案提供的打字部分。