TypeScript获取苗条组件的 prop 类型

8xiog9wr  于 2022-12-27  发布在  TypeScript
关注(0)|答案(4)|浏览(203)

假设您正在使用从其他地方导入的组件
第一个月
你想传递给它一个你期望从其他地方得到的变量

<script lang="ts">
import Animal from 'animals'
export let animalSpecies : ???
</script>

<Animal species={animalSpecies} />

一种方法是进入源文件,找到直接导入类型的方法,但是有没有可能直接从组件中检索类型呢?
例如,如果有一种方法可以得到typeof:
export let animalSpecies : ComponentType<Animal.species>

juzqafwq

juzqafwq1#

安东尼的回答对我不起作用--它把所有的 prop 都转换成了可选的。
然而,我能够使用以下:

import type { SvelteComponentTyped } from "svelte";
export type Props<T> = T extends SvelteComponentTyped<infer P, any, any> ? P : never;

// and a bonus:
export type Events<T> = T extends SvelteComponentTyped<any, infer E, any> ? E : never;
export type Slots<T> = T extends SvelteComponentTyped<any, any, infer S> ? S : never;
093gszye

093gszye2#

这对我有用

// This returns all the component's properties as a Partial: { prop1?: string, ... }
type ComponentProperties<T extends { $set: (...args: any) => any}> = 
  NonNullable<Parameters<T['$set']>[0]>;

// This returns the type of a specific property
type ComponentPropertyType<
  T extends { $set: (...args: any) => any}, 
  P extends keyof ComponentProperties<T>
> = NonNullable<ComponentProperties<T>[P]>;

用法:

export let animalSpecies: ComponentPropertyType<Animal, 'species'> = ...;
slwdgvem

slwdgvem3#

这也可以使用现在可用的内置Svelte类型:

<script lang="ts">
  import type { ComponentProps } from 'svelte';
  import Animal from 'animals';
  // The below has the types of all props on the Animal component now
  export type AnimalPropTypes = ComponentProps<Animal>;
</script>
w8f9ii69

w8f9ii694#

这是一个使用泛型的例子。如果你需要Typescript来推断来自库的类型,这将特别有用,因为你可能不想在这里导入或复制第三方类型定义以保持清晰的边界。
如果不使用泛型,Typescript将无法编译下面的代码,因为gridProps中的某些字段将被视为any。使用泛型,Typescript能够将值与库所需的类型进行匹配。
示例(使用AG Grid):

<!-- grid.svelte -->
<script lang="ts">
    type T = $$Generic;
    interface $$Props {
        options: GridOptions<T>;
    }

    export let gridOptions: GridOptions<T>;
</script>

<!-- component.svelte -->
<script lang="ts">
    import Grid from './grid.svelte';
    import type { ComponentProps } from 'svelte';

    let rowData = [
        // insert your data here
    ];

    type T = typeof rowData[number];
    const gridProps: ComponentProps<Grid<T>> = {
        gridOptions: {
            // type infer now works
        }
    };
</script>

<Grid {...gridProps} />

相关问题