typescriptsvelte

How do I create a custom input svelte component and reuse prop types?


I'm trying to create a wrapped version of an input component with a label, I want it to have all the same attributes as the normal input field, as well as the "label".

I'm slightly confused about how to import the type definition and to type the attributes properly.

<style>
    input {
        width: 100%;
        display: block;
    }
</style>

<script lang="typescript">
    import { SvelteInputProps } from 'svelte'
    export let label: string = '' 
    type $$Props = SvelteInputProps;
</script>

<label>
    {label}
    <input {...$$props} />
</label>

like this in react:

interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
    label: string
}

export default function Input (props: Props) {
    const { label, ...inputProps } = props;
    return (
        <label>
            {label}
            <input {...inputProps}></input>
        </label>
    )
}

Solution

    1. I suggest changing $$props to $$restProps. $$restProps includes all the props not explicitly exported, which means the label prop is excluded, which is likely what you want.
    2. I suggest changing lang="typescript" to lang="ts", which will become the only valid way of signaling that the script code is TypeScript in the long run.
    3. To express "extend from all valid input props", write interface $$Props extends .. { label: string } where .. is something you need to define yourself for now. You can take the contents of the HTMLAttributes definition as a start (ignoring the interfaces it extends from) and remove all properties that are not valid on input, or accept that this includes more than possible.
    <style>
        input {
            width: 100%;
            display: block;
        }
    </style>
    
    <script lang="ts">
        import type { SvelteInputProps } from './filepath-to-your-typings'
        export let label: string = '' 
        interface $$Props extends SvelteInputProps {
            label: string;
        }
    </script>
    
    <label>
        {label}
        <input {...$$restProps} />
    </label>