Last active
May 27, 2018 15:19
-
-
Save sliekens/6a756add830c919ad188dbbcbc60697f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Hero { | |
id: number; | |
name: string; | |
superpower: Power; | |
friends: Hero[]; | |
} | |
export class Power { | |
name: string; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO: add conditional type for arrays (meaning when T[K] is an array) (requires TS 2.8, planned for NG 6.1) | |
// until then, simply do a manual cast from `Like<T[K][]>` to `Like<T[K]>[]` | |
export type Like<T> = { | |
[K in keyof T]: T[K] | Like<T[K]> | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is how we used to write TypeScript | |
// Declare anonymous objects as Hero | |
const windstorm: Hero = { | |
id: 1, | |
name: 'Windstorm', | |
superpower: { | |
name: 'Storm manipulation' | |
}, | |
friends: [ | |
{ ... }, | |
{ ... }, | |
{ ... } | |
] | |
}; | |
// Now you get the following intellisense | |
// windstorm: Hero | |
// windstorm.id: number; | |
// windstorm.name: string; | |
// windstorm.superpower: Power; | |
// windstorm.superpower.name: string; | |
// windstorm.friends: Hero[]; | |
// but these are lies: windstorm's prototype is actually Object, not Hero | |
const isHero = windstorm instanceof Hero; // false | |
// same for superpower | |
const isPower = windstorm.superpower instanceof Power; // false | |
// same for friends | |
const areHeroes = windstorm.friends.every(friend => friend instanceof Hero); // false, false, false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is how I write TypeScript now | |
// Declare anonymous objects as Like<Hero> instead of Hero | |
const windstorm: Like<Hero> = { | |
id: 1, | |
name: 'Windstorm', | |
superpower: { | |
name: 'Storm manipulation' | |
}, | |
friends: [ | |
{ ... }, | |
{ ... }, | |
{ ... } | |
] | |
}; | |
// Now you get the following intellisense | |
// windstorm: Like<Hero> | |
// windstorm.id: number; | |
// windstorm.name: string; | |
// windstorm.superpower: Power | Like<Power>; | |
// windstorm.superpower.name: string; | |
// windstorm.friends: Hero[] | Like<Hero[]>; | |
// instanceof Hero is still false, but this time you would have expected that, because intellisense | |
const isHero = windstorm instanceof Hero; // false, but not unexpected | |
// same for superpower | |
const isPower = windstorm.superpower instanceof Power; // false, but not unexpected | |
// same for friends | |
const areHeroes = windstorm.friends.every(friend => friend instanceof Hero); // false, false, false | |
// The only problem right now: TS <2.8 doesn't have conditional types | |
// ideally we would want `friends` to be typed like this: | |
// windstorm.friends: Hero[] | Like<Hero>[]; | |
// this should be possible starting with TS 2.8 but I'm waiting for NG 6.1 to make it happen |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment