Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@aiya000
Last active July 8, 2019 05:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aiya000/5f12ca0276eabaf6bf1331ee2cd96fae to your computer and use it in GitHub Desktop.
Save aiya000/5f12ca0276eabaf6bf1331ee2cd96fae to your computer and use it in GitHub Desktop.
Typgin NativeScript's untyped Observable
/**
* Declare a type T of a property K via K of a type X.
*
* - Field<{foo: number, bar: string}, 'foo', number> = 'foo'
* - Field<{foo: number, bar: string}, 'bar', string> = 'bar'
* - Field<{foo: number, bar: string}, 'foo', string> = never
*/
export type Field<X, K extends string, T> = K extends keyof X
? T extends X[K] ? K : never
: never
import * as Untyped from 'tns-core-modules/data/observable'
import deprecated from 'deprecated-decorator' // npm install --save-dev deprecated-decorator
import { Field } from '@/data/conditional-types'
/**
* Don't dirty your hands.
* You must use this instead of [[Untyped.Observable]].
*
* This description is [here](http://aiya000.github.io/posts/2019-07-04-recover-nativescript-type-unsafe-observable.html).
*/
export default class Observable<X extends object> extends Untyped.Observable {
constructor() {
super()
}
/**
* A typed safety set()
*/
public assign<K extends string, T>(name: Field<X, K, T>, value: T): void {
super.set(name, value)
}
@deprecated('assign')
public set(name: string, value: any): void {
super.set(name, value)
}
/**
* A type safety get()
*/
public take<K extends string, T>(key: Field<X, K, T>): T | null {
return super.get(key) || null
}
@deprecated('take')
public get(name: string): any {
super.get(name)
}
}
const p = new Observable<{ x: number, y: string }>()
p.assign('x', 10)
p.assign('y', 'poi')
// 2345: Argument of type '"y"' is not assignable to parameter of type 'never'.
// p.assign('y', 10)
const x: number = p.take('x')
const y: string = p.take('y')
// 2345: Argument of type '"y"' is not assignable to parameter of type 'never'.
// const e: number = p.take('y')
// Use {x?: number, y?: string} if you are careful to forget initializing :D
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment