How to type cast Svelte 3 reactive syntax variables?
Asked Answered
P

3

12

I don't know how to type Svelte 3 reactive syntax variables.

<script lang="ts">
  import type { Player, Team } from "./types";

  import { DEFAULT_PLAYER } from "./utils";

  $: player = DEFAULT_PLAYER as Player;
    $: team = { search: "Real", players: [] } as Team;
</script>

But this doesn't work:

'Team' cannot be used as a value because it was imported using 'import type'.ts(1361)

If I use this instead:

$: team = ({ search: "Real", players: [] } as Team);

the VSCode extension svelte.svelte-vscode format it like the first one when I save.

Is this my fault?

Is there a better way to cast those reactive vars?

Petropavlovsk answered 2/6, 2021 at 10:13 Comment(0)
K
29
<script lang="ts">
  import type { Player, Team } from "./types";

  import { DEFAULT_PLAYER } from "./utils";

  let player: Player;
  $: player = DEFAULT_PLAYER;
  let team: Team;
  $: team = { search: "Real", players: [] };
</script>

I'm not a fan of using as to type cast and will avoid it at all possible. Type casting with as can lead to runtime type errors because you're telling the compiler "this variable will always be this type, trust me".

Instead, declare your reactive variable first with the type declaration. In the above case…

<script lang='ts'>
  let team: Team;
  $: team = { search: "Real", players: [] }
</script>

… no type casting needed!

Kiefer answered 4/6, 2021 at 2:44 Comment(0)
A
5

When working with TypeScript in 2023, it is recommended to use the satisfies operator for better type safety. Consider the following code snippet:

<script lang="ts">
  import type { Player, Team } from "./types";
  import { DEFAULT_PLAYER } from "./utils";

  $: player = DEFAULT_PLAYER satisfies Player;
  $: team = { search: "Real", players: [] } satisfies Team;
</script>

This approach offers improved conciseness and avoids the need for redundant declarations.

Previously, I encountered issues while using the let method, as it didn't provide strict enforcement of object properties. For instance, the following failure is correctly identified:

type A = { a: string };
let a: A;
$: a = { a: 2 };

However, the following case does not cause a type error even though it should:

type A = { a: string };
let a: A;
$: a = { a: 'a', b: 'b' };

This situation poses a significant problem, as it allows unintended properties to be added to objects.

Augmented answered 8/6, 2023 at 16:7 Comment(1)
@Kiefer answered correctly at the time he did it. But your answer is definitely should be in top now, thanks!Kornher
P
2

I think you should do

<script lang="ts">
  import type { Player, Team } from "./types";

  import { DEFAULT_PLAYER } from "./utils";

  let team: Team;  // added this
  $: player = DEFAULT_PLAYER as Player;
    $: team = { search: "Real", players: [] };
</script>
Pylorectomy answered 2/6, 2021 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.