Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discriminating union does not work in template #11257

Closed
TomDo1234 opened this issue Apr 20, 2024 · 2 comments
Closed

Discriminating union does not work in template #11257

TomDo1234 opened this issue Apr 20, 2024 · 2 comments

Comments

@TomDo1234
Copy link

Describe the bug

Discriminating union does not work in template

Reproduction

Context on the type

type ServiceData = {
    type: string;
    value: string | number | string[];
    updatable?: boolean | undefined;
    datalist?: string | undefined;
} | {
    type: 'nested_array';
    data: Record<string, ServiceData>;
}

The issue

{#if lol.type === 'nested_array'}
    {lol.data} //This errors in intellisense
{/if}

<script lang="ts">
    import type { ServiceData } from '../../types';

    let lol: ServiceData = { type: 'nested_array',data: {}};

    if (lol.type === 'nested_array') {
        console.log(lol.data) //this does not
    }
</script>

Can the svelte team fix this, and is there a work around?

Logs

No response

System Info

System:
    OS: Linux 6.8 Arch Linux
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-11320H @ 3.20GHz
    Memory: 8.64 GB / 15.41 GB
    Container: Yes
    Shell: 5.2.26 - /usr/bin/bash
  Binaries:
    Node: 18.20.2 - ~/.nvm/versions/node/v18.20.2/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v18.20.2/bin/npm
    pnpm: 8.15.6 - ~/.nvm/versions/node/v18.20.2/bin/pnpm
  npmPackages:
    svelte: ^4.2.7 => 4.2.13

Severity

annoyance

@brunnerh
Copy link
Member

Wonder if Svelte can do much here, these types don't really work.

If you union string with 'string literal' the result is always string.

The if type narrowing in the script block only works due to flow analysis, i.e. there is no code changing the variable before the if, hence the type at that point is inferred to be that of the data provided in the declaration, rather than ServiceData whose type prop is useless.

E.g.

// no error
let sd: ServiceData = { type: 'nested_array', data: {} };
if (sd.type == 'nested_array') {
	console.log(sd.data);
}

// error
function getData(): ServiceData {
	return { type: 'nested_array', data: {} };
}

let sd2: ServiceData = getData();
if (sd2.type == 'nested_array') {
	console.log(sd2.data);
}

Playground

@dummdidumm
Copy link
Member

As pointed out, the union type needs something to clearly discriminate against, and string widens the type such that it no longer works. Closing as there's nothing Svelte can do

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants