首页 > 解决方案 > 是否可以在苗条的每个块内进行类型转换

问题描述

我有这些类型:

type Exercise = {
 type: string
 prompt: string
 answer: string
}

type ComplexExercise = {
  type: string
  prompt: string,
  subExercises: Exercise[]
}

我试图制作一个从 api 获取数据并根据类型呈现它的组件

<script lang="ts">
  let promise = getExercise(params.exerciseId).then((ex) => (exercise = ex));
  let exercise: ComplexExercise | Exercise;
</script>
...

{#await promise}
  <p>Loading exercise</p>
{:then}
  {#if exercise.type !== "COMPLEX"}
    <BaseEditor {exercise} />
  {:else}
    {#each exercise.subExercises as ex}
      <BaseEditor {ex} />
    {/each}
  {/if}
{/await}

我收到以下错误

Property 'subExercises' does not exist on type Exercise

投射它会引发此错误

{#each (exercise as ComplexExercise).subExercises as ex}
                 ^ Unexpected token svelte(parse-error)

唯一可行的是将运动类型设置为任何类型,出于显而易见的原因,我正在避免它。任何帮助表示赞赏

标签: typescripttypescript-typingssvelte

解决方案


更改您的类型以使用可区分的联合类型。这意味着,TS 可以确定它是哪种具体类型有一个共同的属性。在您的情况下,该属性是type. 假设您只有这两种运动类型:

type Exercise = {
 type: "SIMPLE"
 prompt: string
 answer: string
}

type ComplexExercise = {
  type: "COMPLEX"
  prompt: string,
  subExercises: Exercise[]
}

如果这样做,TS 将通过{#if exercise.type !== "COMPLEX"}else 块中的类型知道类型,ComplexExercise并且类型错误将消失。

有关受歧视工会的更多信息:https ://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions


推荐阅读