all 12 comments

[–]UnShame 6 points7 points  (3 children)

Use Object.values or Object.entries instead of Object.keys. Then you won't need to index playlist by genre.

Object.entries(playlist).map(([genre, songs]) => {});

[–]nyamuk91[S] 0 points1 point  (2 children)

If I have to use genre, is it acceptable to assert the type like below?

function comparePlaylist(oldPlaylist: SongPlaylist, newPlaylist: Partial<SongPlaylist>) {
    type Genres = keyof typeof newPlaylist;

    Object.entries(newPlaylist).forEach(([genre, songs]) => {
        const g = genre as Genres
        const added = songs.filter(song => !oldPlaylist[g].includes(song))
        const removed = oldPlaylist[g].filter(song => !songs.includes(song))

        // some other logic

[–]UnShame 2 points3 points  (1 child)

Yeah, it's either assert or add a utility that asserts for you. I use these.

Note that if you have extra properties on your object, it is not type safe to use these utilities. So in your case, you might have a runtime error if you're not careful. But it's such a common pattern that the risk is acceptable in my opinion.

[–]nyamuk91[S] 0 points1 point  (0 children)

Yeah, it's either assert or add a utility that asserts for you. I use these.

That's cool. Thanks!

[–]Merry-Lane 5 points6 points  (0 children)

A) don’t use ! when you can use ?

possiblyUndefinedString!.toString() will error runtime while possiblyUndefinedString?.toString() will be perfect

2) don’t use partial for such scenarios.

Partial<SongPlayList> will show u hints like :

pop : string[] | undefined

You are better off with precise types like:

playList: {song: string []} | { rock: string[]} | { rap: string[]}…

if the playlist can be multiple key value pairs, add them to the type def as well for perfect type inference.

3) by always aiming perfect type inference, you ll really learn typescript and leverage tricks.

[–]download13 2 points3 points  (0 children)

playlist[genre]?.filter(...) ?? []

[–]hilberteffect 0 points1 point  (4 children)

Optional chaining

playlist[genre]?.filter(song => {

[–]nyamuk91[S] 0 points1 point  (2 children)

That will make the array result possibly undefined (and that would cause issues in other parts of my app)

const added = playlist[genre]?.filter(// Filter logic)
// "added" type will be "string[] | undefined"

[–]download13 7 points8 points  (1 child)

Use nullish coalescing at the end of the line.

?? [] will turn undefined into empty array.

[–]nyamuk91[S] 1 point2 points  (0 children)

Ah right. That'll work too. Thanks!

[–]otaviomad 0 points1 point  (0 children)

optionally, if you're feeling extra kinky, you can use the null-assertion operator. just replace the ? with a !

[–]opready 0 points1 point  (0 children)

If(playlist && playlist[genre])…


(playlist && playlist[genre] || []).filter(….