# Typescript support for variants

**URL:** <https://forum.dfinity.org/t/typescript-support-for-variants/7205>\
**Category:** Language Support\
**Created:** [September 13, 2021, 11:10am UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205 "2021-09-13T11:10:37Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alexeychirkov](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alexeychirkov/32/1991_2.png) [@alexeychirkov](https://forum.dfinity.org/u/alexeychirkov)\
**Post date:** [September 13, 2021, 11:10am UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/1 "2021-09-13T11:10:37Z")

</div>

Currently variant in typescript looks like this:

```auto
type MyVariant = { "ok" : string } | { "err" : string }

```

It is hard to use type predicates.

I think it would be great to have following:

```auto
type Type_1 = { "ok" : string }
type Type_2 = { "err" : string }
type MyVariant = Type_1 | Type_2

```

Now we can use type predicates:

```auto
function isType1(value: Type_1 | Type_2): value is Type_1 {
    return (value as Type_1).hasOwnProperty("ok");
}

function isType2(value: Type_1 | Type_2): value is Type_2 {
    return (value as Type_2).hasOwnProperty("err");
}

```

What gives us:

```auto
function myFunc(a: MyVariant) {
    if (isType1(a)) {
        let err = a.err;//TS2339: Property 'err' does not exist on type 'Type_1'.
        let ok = a.ok;
    } else if (isType2(a)) {
        let err = a.err;
        let ok = a.ok;//TS2339: Property 'ok' does not exist on type 'Type_2'.
    }
}

```

Profit!

@anon74414410 Please tag someone who can help

Thanks!

---

<div class="post-metadata">

**Author:** ![anon74414410](https://avatars.discourse-cdn.com/v4/letter/a/85f322/32.png) [@anon74414410](https://forum.dfinity.org/u/anon74414410)\
**Post date:** [September 13, 2021, 4:02pm UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/2 "2021-09-13T16:02:29Z")

</div>

@chenyan @claudio we’ve discussed this before internally, but here’s some community feedback

---

<div class="post-metadata">

**Author:** ![alexeychirkov](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alexeychirkov/32/1991_2.png) [@alexeychirkov](https://forum.dfinity.org/u/alexeychirkov)\
**Post date:** [September 23, 2021, 6:15pm UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/3 "2021-09-23T18:15:54Z")

</div>

@anon74414410, are there any improvements in the roadmap?  
Thanks in advance

---

<div class="post-metadata">

**Author:** ![chenyan](https://avatars.discourse-cdn.com/v4/letter/c/35a633/32.png) [@chenyan](https://forum.dfinity.org/u/chenyan)\
**Post date:** [September 23, 2021, 6:35pm UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/4 "2021-09-23T18:35:45Z")

</div>

I don’t know typescript well, but does the following work?

```auto
function myFunc(a: MyVariant) {
  if (a.hasOwnProperty("ok")) {
    let ok = a.ok;
  } else if (a.hasOwnProperty("err")) {
    let err = a.err;
  }
}

```

---

<div class="post-metadata">

**Author:** ![shalexbas](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/shalexbas/32/2139_2.png) [@shalexbas](https://forum.dfinity.org/u/shalexbas)\
**Post date:** [October 13, 2021, 2:30pm UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/5 "2021-10-13T14:30:06Z")

</div>

For TS generation, wouldn’t it be better to generate variants like this:

```auto
instead of:
type MyVariant = { "ok" : string } | { "err" : string }

this:
type MyVariant = { type: "ok"; val: string} | { type: "err"; val: string }

because this is the way ts defines discriminated unions and you can write code like:
if (c1.type === "ok") {
    //compiler will narrow the type to "ok", exhaustive switch blocks are also possible
    const c2 = c1;
  }

```

Alternatively I suggest to try out [ts-pattern - npm](https://www.npmjs.com/package/ts-pattern) , then it should be possible to do pattern matching on the current implementation. You can write code like (didn’t tested, but it looks like compiler doesn’t complain):

```auto
  const a1: Result = a();

  const output = match(a1)
    .with({ Ok: __ }, (myOk) => {
      //type is narrowed
      const ok = myOk.Ok;
    })
    .with({ Err: __ }, (myErr) => {
      const err2 = myErr.Err;
      match(err2)
        .with({ RegistrationFailed: __ }, (p) => "{}")
        .with({ AccountAlreadyRegistered: __ }, (p2) => "{}")
        .exhaustive();
    })
    .exhaustive();

```

---

<div class="post-metadata">

**Author:** ![alexeychirkov](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alexeychirkov/32/1991_2.png) [@alexeychirkov](https://forum.dfinity.org/u/alexeychirkov)\
**Post date:** [October 14, 2021, 1:39pm UTC](https://forum.dfinity.org/t/typescript-support-for-variants/7205/6 "2021-10-14T13:39:57Z")

</div>

@shalexbas Thank you so much for provided approach!
