编辑:答复https://svelte.dev/repl/eb7616fd162a4829b14a778c3d1627e4?version=3.48.0

我所说的将导致:

首先,我们有一个按钮:

<button on:click={add}> Add </button>
<div id="columnflexbox">

当我单击它时,应该会发生以下情况:

<button on:click={add}> Add </button>
<!-- This exists in DOM-->
<div id="columnflexbox">

<!-- This div and components get rendered, the Div does not exist in DOM -->
<div class="row" style="display:flex;flex-direction:row">
comp1 (instance1) 
comp2 (instance1)
</div>

再次单击时,会添加另一行(带有新实例):

<div id="columnflexbox">


<div class="row" style="display:flex;flex-direction:row">
comp1 (instance1) 
comp2 (instance1)
</div>
<!-- Second div is generated, it does not exist in DOM, new instances of components -->
<div class="row" style="display:flex;flex-direction:row">
comp1 (instance2)
comp2 (instance2)
</div>


</div>

有一个接口:

export interface complexObject {
    comp1 : ComplexObj1
    comp2: ComplexObj2
}

let row: complexObject[] = []

添加功能:

function add(){        
    let newObj:complexObject = {
        comp1: new Comp1({target: div}), // I have to add a target here, or I get compile error, but how since the element doesn't exist?
        comp2: new Comp2({target: div})
    }

    row.push(newObj);
}

我会使用这种方法,但我不能,因为我在没有添加目标的情况下会出现编译错误:

{#each row as rowitem }

    <div class="row">
        {rowitem.comp1}
        {rowitem.comp2}
    </div>
    
{/each}

编辑:结果表明,当我将目标添加为渲染中指定的html时,样式得到了正确应用,如下所示:

添加功能:

function add(){    
    let div = document.createElement("div");
    div.setAttribute('class',"row")


    let newObj:complexObject = {
        comp1: new Comp1({target: div}),
        comp2: new Comp2({target: div})
    }

    row.push(newObj);
}


{#each row as rowitem }
<div class="row">
        {rowitem.comp1}
        {rowitem.comp2}
</div>    
        

{/each}

现在的问题是组件没有被渲染,我得到的是

[object Object]     [object Object]

当我try 这样渲染时:

  <svelte:component this={rowitem.comp1}>

    </svelte:component>

I get错误:

TypeError: l is not a constructor

如果我try 修改Add函数并删除new个关键字,我会得到以下结果:

Type 'typeof comp1__SvelteComponent_' is missing the following properties from type 'comp1__SvelteComponent_': $$prop_def, $$events_def, $$slot_def, $on, and 5 more.ts(2740)

事实证明,这是指定接口的问题,应该这样指定:

export interface complexObject {
    comp1 : typeof ComplexObj1
    comp2: typeof ComplexObj2
}

推荐答案

为此,通常会使用svelte:component,它使用组件的构造函数作为输入,并使用任何可能需要传递的props .例如

<script>
    import Comp from './Comp.svelte';
    
    let components = [
        [Comp, { content: 'Initial' }],
        [Comp, { content: 'Initial 2' }],
    ];
    function add(component, props) {
        components = [...components, [component, props]];
    }
</script>

<button type=button on:click={() => add(Comp, { content: 'Added' })}>
    Add
</button>

{#each components as [component, props]}
    <svelte:component this={component} {...props}>
        (Slotted content)
    </svelte:component>
{/each}

REPL example


类型示例:

<script lang="ts">
    import type { SvelteComponent, SvelteComponentTyped } from 'svelte';
    import Comp from './Comp.svelte';
    import Comp2 from './Comp2.svelte';
    
    let components: [typeof SvelteComponent, Record<string, any>][] = [
        [Comp, { content: 'Initial' }],
        [Comp2, { color: 'blue' }],
    ];
    function add<T extends typeof SvelteComponentTyped<P, any, any>, P>(
        component: T,
        props: P
    ) {
        components = [...components, [component, props]];
    }
</script>

add强制组件及其props 之间的一致性,数组不能,至少在使用元组时不能.如果每个项都是一个类,则该类可以强制实现其内部类型一致性.

Typescript相关问答推荐

如何在类型脚本中使用条件陈述循环

如何使用另一个类型的属性中的类型

从接口创建类型安全的嵌套 struct

在泛型类型中对子代执行递归时出错

如何推断计算逻辑的类型

TypeScrip原始字符串没有方法

使用Dockerfile运行Vite React应用程序时访问env变量

类型TTextKey不能用于索引类型 ;TOption

TypeError:正文不可用-NextJS服务器操作POST

在列表的指令中使用intersectionObservable隐藏按钮

如何在方法中正确地传递来自TypeScrip对象的字段子集?

在VSCode中显示eslint错误,但在终端中运行eslint命令时不显示?(Vite,React,TypeScript)

编译TypeScrip项目的一部分导致错误

将对象的属性转换为正确类型和位置的函数参数

如何在Angular 服务中制作同步方法?

如何编辑切片器以使用CRUD调用函数?

如何键入并类型的函数&S各属性

KeyOf关键字在特定示例中是如何工作的

Typescript不允许在数组中使用联合类型

Karma Angular Unit测试如何创建未解析的promise并在单个测试中解决它,以判断当时的代码是否只在解决后运行