Skip to content

Instantly share code, notes, and snippets.

@axxag
Last active May 11, 2017 04:35
Show Gist options
  • Save axxag/cac5b64267c6441d31a20d4f38f735f4 to your computer and use it in GitHub Desktop.
Save axxag/cac5b64267c6441d31a20d4f38f735f4 to your computer and use it in GitHub Desktop.
// Define our record defaults
const fruitDefaults = {
name: '',
numberOwned: 0,
best: false,
}
// Define our record types with a typescript interface
interface IFruitParams {
name: string;
numberOwned: number;
best: boolean;
}
// Create our FruitRecord class
export class FruitRecord extends Record(fruitDefaults) {
// Set the params. This will also typecheck when we instantiate a new FruitRecord
constructor(params: IFruitParams) {
super(params);
}
// This following line is the magic. It overrides the "get" method of record
// and lets typescript know the return type based on our IFruitParams interface
get<T extends keyof IFruitParams>(value: T): IFruitParams[T] {
// super.get() is mapped to the original get() function on Record
return super.get(value)
}
}
// Now typescript will properly enforce our record types
// and will make sure we don't try to get() any values that aren't declared!
const bestFruit = new FruitRecord({
name: 'blueberry',
numberOwned: 10,
best: true
})
// Test Case #1
// returns true
isBestFruit(bestFruit.get('name'))
// Test Case #2
// returns typescript error - 'best' (boolean) is not assignable to string
isBestFruit(bestFruit.get('best'))
// Test Case #3
// returns typescript error - 'worst' property does not exist on bestFruit
const isWorst = bestFruit.get('worst')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment