DEV Community

E.R. Nurwijayadi
E.R. Nurwijayadi

Posted on • Edited on

Typescript: Playing with Interface

This post was originally posted on my personal blog 😀. The source code example also provided in github, given in that blog.

🕷 Typescript - Small Step into Typed

Goal

Goal: A small step into typescript using custom song script example.

I make this case example, because I want to learn typescript. The task is simply to collect unique tags from records.


Type Basic

Consider start from simple. This is a conventional function in typescript:

const func = function(a: number, b: number): number { return a+b; } const z: number = func(6,7) console.log (z) 
Enter fullscreen mode Exit fullscreen mode

We can rewrite using ES6's fat arrow, with about the same result, as below code:

const func = (a: number, b: number): number => a+b; const z: number = func(6,7) console.log (z) 
Enter fullscreen mode Exit fullscreen mode

Or even better with some kind of function signatures, with about the same result, as below code:

type MyFunc = (a: number, b: number) => number; const func: MyFunc = (a, b) => a + b; const z: number = func(6,7) console.log (z) 
Enter fullscreen mode Exit fullscreen mode

You can spot the detail. This looks like type signature in functional programming.

Now let's get down to a record case example.


Data Structure: Original in Javascript

Consider a case example of some popular songs from the old decades.

With javascript, I can just write away the records in below form:

const songs = [ { title: "Cantaloupe Island", tags: ["60s", "jazz"] }, { title: "Let it Be", tags: ["60s", "rock"] }, { title: "Knockin' on Heaven's Door", tags: ["70s", "rock"] }, { title: "Emotion", tags: ["70s", "pop"] }, { title: "The River" } ]; export default songs; 
Enter fullscreen mode Exit fullscreen mode

Data Structure: Ported to Typescript

With Typescript, you can peacefully append additional interface signature.

interface Song{ readonly title: string; readonly tags?: Array<string>; } const songs: Array<Song> = [ { title: "Cantaloupe Island", tags : ["60s", "jazz"] }, { title: "Let it Be", tags : ["60s", "rock"] }, { title: "Knockin' on Heaven's Door", tags : ["70s", "rock"] }, { title: "Emotion", tags : ["70s", "pop"] }, { title: "The River" } ]; export { Song, songs }; 
Enter fullscreen mode Exit fullscreen mode

 Data Structure: Ported to Typescript


Procedural: in Javascript

In the old glorious days of Javascript, common approach to solve unique array in records is, by using loop.

let tagSet = new Set(); // using set feature to collect tag names songs.forEach(function(song) { if( "tags" in song ) { let tags = song.tags; console.log(tags); for (const tag of tags) { tagSet.add(tag); } } }); console.log(tagSet); // normalize to array let alltags = [...tagSet]; console.log(alltags); 
Enter fullscreen mode Exit fullscreen mode

Well, not so old, this is already using ecmascript 2015.


Functional: in Javascript

These days with ecmascript 2019 we can use flatMap, so the code can be shorter.

import songs from "./songs-data.js"; const unique = array => [... new Set(array)]; const allTags = unique(songs .filter(song => song.tags) .flatMap(song => song.tags) ); console.log(allTags ); 
Enter fullscreen mode Exit fullscreen mode

Functional: in Javascript


Type Interface: in Typescript

With the right code, it is fun to type the interface signature.

import { Song, songs } from "./songs-data"; type Unique = (array: Array<string>) => Array<string>; const unique : Unique = (array) => [... new Set(array)]; type PickTags = (song: Song) => Array<string>; const pickTags : PickTags = (song) => song.tags! const allTags: Array<string> = unique(songs .filter( pickTags ) .flatMap( pickTags ) ); console.log(allTags ); 
Enter fullscreen mode Exit fullscreen mode

Type Interface: in Typescript

There are details to achieve this in provided link above.
I just want this notes to be short. So I strip out the details here.


Type Interface: with Deno (also Typescript)

However, beware of the difference between ts-node and deno.

All the codes above works well, except we need an adjustment for export import.

This picture should be enough to show the issue

Deno Issue: Type Interface

Export Interface

Instead of ts-node style below:

interface Song{ … } … export { Song, songs }; 
Enter fullscreen mode Exit fullscreen mode

We should use export reserved word as below:

export interface Song{ … } … export { songs }; 
Enter fullscreen mode Exit fullscreen mode

Import

Now you can import as usual, except you must specify, the file extension .ts.

import { Song, songs } from "./songs-data.ts"; 
Enter fullscreen mode Exit fullscreen mode

The script should works well.
This is the only issue I face so far.
And it has been solved already.


Conclusion

Once I step into this typescript.
It doesn't seems to be scary anymore.
In fact this looks fun.
I should play with language more often.

What do you think?

Top comments (0)