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

Svelte 5 - $dervied causes svelte-check errors that do not occur with $derived.by #11090

Closed
eighty4 opened this issue Apr 7, 2024 · 4 comments

Comments

@eighty4
Copy link

eighty4 commented Apr 7, 2024

Describe the bug

The following typings (a nullable state and a function signature with an optional param that derives another value) produce a type error Error: Property 'elements' does not exist on type 'never'.

Example code that produces the error:

export interface InspectResult {
    elements: Array<Element>
    point?: Point
    selector?: string
}

function buildBoundingBoxes(elements?: Array<Element>): Array<BoundingBox> | null {
}

let inspectResult: InspectResult | null = $state(null)
let boundingBoxes: Array<BoundingBox> | null = $derived(buildBoundingBoxes(inspectResult?.elements))

The fix was to use $derived.by for code that should be valid with $derived. Either $derived or $derived.by work at runtime the same. The only problem was the type error during svelte-check.

Reproduction

With the $derived type error

With the $derived.by fix

Logs

!~/work/eighty4/qwerky/ui pnpm check

> ui@0.0.1 check /Users/adam/work/eighty4/qwerky/ui
> svelte-kit sync && svelte-check --tsconfig ./tsconfig.json


====================================
Loading svelte-check in workspace: /Users/adam/work/eighty4/qwerky/ui
Getting Svelte diagnostics...

/Users/adam/work/eighty4/qwerky/ui/src/lib/header/qwerky_header.svelte:205:9
Warn: Unknown property: 'text-fill-color' (css)
        color: #000;
        text-fill-color: transparent;
        -webkit-text-fill-color: transparent;


/Users/adam/work/eighty4/qwerky/ui/src/lib/qwerky_app.svelte:18:95
Error: Property 'elements' does not exist on type 'never'. (ts)
    let inspectResult: InspectResult | null = $state(null)
    let boundingBoxes: Array<BoundingBox> | null = $derived(buildBoundingBoxes(inspectResult?.elements))



====================================
svelte-check found 1 error and 1 warning in 2 files
 ELIFECYCLE  Command failed with exit code 1.

System Info

System:
    OS: macOS 14.4.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 318.56 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - /usr/local/bin/node
    npm: 10.1.0 - /usr/local/bin/npm
    pnpm: 8.6.3 - /usr/local/bin/pnpm
  Browsers:
    Chrome: 123.0.6312.107
    Safari: 17.4.1
  npmPackages:
    svelte: 5.0.0-next.95 => 5.0.0-next.95

Severity

annoyance

@7nik
Copy link

7nik commented Apr 8, 2024

Obviously, the concept of reactive expressions doesn't even exist in TS. So TS thinks that when buildBoundingBoxes(inspectResult?.elements)) is executed, inspectResult can only be null. And then it seems to face this issue microsoft/TypeScript#41766.

It seems another workaround is inspectResult!?.elements.

@dummdidumm
Copy link
Member

Yeah this is a type narrowing issue, and the type is widened in the lambda.
Another way to get around it is to type the $state generic: let foo = $state<boolean | null>(null)

Giving this the documentation label because there's not much we can do.

@eighty4
Copy link
Author

eighty4 commented Apr 13, 2024

Why wouldn't derived.by be the API style of derived and drop derived.by? I'm not sure why compiler magic that necessitates a duplicate rune to work around trumps having a natural API.

@7nik
Copy link

7nik commented Apr 13, 2024

@eighty4 it was discussed multiple times, including in the initial #10240

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

3 participants