-
Notifications
You must be signed in to change notification settings - Fork 644
Proper typescript typings #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hmm typewise the most safe approach is to let all factories only return their target type, and introduce a static function createFactory<T>(base: T): T {
return null as any
}
function primitive<T>(value: T): T {
return null as any
}
const A = createFactory({
x: primitive(3 as number),
y: primitive("boe" as string)
})
function create<T>(f: T): T {
return null as any
}
// factory is invokable
const a = create(A)
// property can be used as proper type
const z: number = a.x
// property can be assigned to crrectly
a.x = 7
// wrong type cannot be assigned
a.x = "stuff" // Red is ok
// sub factories work
const B = createFactory({
sub: A
})
const b = create(B)
// sub fields have proper type
b.sub.x = 4
const d: string = b.sub.y
// sub fields can be reassigned
b.sub = create(A) |
What about this? export type IModel = {
$treenode: any // Actually Node, but that should not be exposed to the public...
} & Object
export interface IFactory<S, T> {
create(snapshot?: S, env?: Object): T & IModel
factoryName: string,
is: ITypeChecker
isFactory: boolean // TODO: rename to isFactory
type: IType
}
export interface IType {
name: string
is(thing: IModel | any): boolean
create(snapshot, environment?): any
factory: IFactory<any, any> // TODO type
describe(): string
}
export type ITypeChecker = (value: IModel | any) => boolean
export type IBaseModelDefinition<S extends Object, T> = {[K in keyof T]: IFactory<any, T[K]> | T[K]}
export function createFactory<S extends Object, T extends S>(baseModel: IBaseModelDefinition<S, T>): IFactory<S, T>
export function createFactory<S extends Object, T extends S>(name: string, baseModel: IBaseModelDefinition<S, T>): IFactory<S, T>
export function createFactory(arg1, arg2?) {
return null as any
}
const t_string: IFactory<string, string> = null as any
const t_number: IFactory<number, number> = null as any
const t_primitive = <T>(value: T) => T
const A = createFactory({
x: t_primitive(3),
y: t_primitive("boe")
})
// factory is invokable
const a = A.create()
// property can be used as proper type
const z: number = a.x
// property can be assigned to crrectly
a.x = 7
// wrong type cannot be assigned
a.x = "stuff" // Red is ok
// sub factories work
const B = createFactory({
sub: A
})
const b = B.create()
// sub fields have proper type
b.sub.x = 4
const d: string = b.sub.y
// sub fields can be reassigned
b.sub = A.create() |
@mweststrate Is the 0.2 API working with Typescript types? On the below example I would expect to have access to the |
Uhm, which TS version are you using @mquandalle ? |
Currently, |
It still doesn't work for me with Typescript 2.2. Here is my Note that the above screenshot comes from my editor but I get corresponding errors (namely |
Yes |
But then again, typescript fails to compile, so I doubt it's an issue with the editor. I see that I have the following error in the console:
|
Ok, the problem was with MobX version. Updating it fixed the issue, sorry for falsy report. |
createFactory
seems to be quite impossible to make strongly typed in Typescript, without mapped types (even when not taking into consideration the partial subtypes of snapshots)Two sample playgrounds demonstrating some of the problems:
fails to reassign subfields
factories are not functions, but expose (possibly null) create method (note the
create!()
)Something like: microsoft/TypeScript#13257 could definitely help!
This is the best I could do so far:
The text was updated successfully, but these errors were encountered: