Search code examples
typescriptaxiossveltetyping

Type issue for a resolved promise (Svelte/TypeScript)


I have the following simplified Svelte code in Typescript:

<script lang="ts">
    import axios from 'axios';
    import { env } from "$env/dynamic/public";
    import type { Submission } from '../models/submission';

    let submissionUuid: string | undefined;
    let submissionStatusResponse = Promise.resolve(String);
    // let submissionStatusResponse = Promise<string>; // not sure about the difference

    const postSubmission = async (file: File): Promise<Partial<Submission>> => {
        const formData = { file: file };
        const { data, status } = await axios.post(env.PUBLIC_API_BASE_URL + '/submissions/', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        });
        if (status === 200) {
            // console.log(JSON.stringify(data));
            return data;
        }
    };

    const getSubmissionStatus = async (uuid: string) => {
        const { data, status } = await axios.get(env.PUBLIC_API_BASE_URL + '/submissions/' + uuid);
        if (status === 200) {
            // console.log(JSON.stringify(data));
            return data.status;
        }
    };

    function handleSubmit() {
        let submissionResponse: Promise<Partial<Submission>> = postSubmission(
            document.getElementById('file').files[0]
        );
        submissionResponse.then((submission) => {
            submissionUuid = submission.uuid;
            submissionStatusResponse = getSubmissionStatus(submissionUuid);
        });
    }
</script>

<form on:submit|preventDefault={handleSubmit}>
    <label for="file">Select a file</label>
    <input type="file" id="file" name="file" required />
    <button type="submit">Submit</button>

    {#await submissionStatusResponse then submissionStatus}
        {submissionStatus}
    {:catch error}
        Error getting submission status from API: {error.message}
    {/await}
</form>

But in the web page the it renders the string function String() { [native code] } instead of the resolved value of submissionStatus.

There must be indeed a type issue since the following Typescript alert is raised on the component Status, when passing the supposedly resolved submissionStatus string: Type 'StringConstructor' is not assignable to type 'string'.

What am I doing wrong here?


Solution

  • The problem is that you are assigning submissionStatusResponse rather than annotating it:

    let submissionStatusResponse = Promise.resolve(String);
    

    So then Promise can resolve String right away. The result is function String() { [native code] } (try doing console.log(String) for comparison).

    I think you want:

    let submissionStatusResponse: Promise<string>; // A promise that will return a string
    

    Then, once the promise is resolved, a string will be returned.