请考虑以下示例:
import { observable } from "mobx";
interface MyObject {
name: string;
age: number;
}
const obj1 = { namee: "Uldis", age: "35" };
type MyObjectObservable = ???;
const obj1Observable: MyObjectObservable = observable(obj1); // I want to have compiler error here
function doStuff(obj: MyObjectObservable) {}
doStuff({ name: "Uldis", age: 35 }) // I want to have compiler error here because passed object is not an observable
应如何定义MyObjectObservable
的类型?我希望拥有尽可能严格的类型,并且我不想使用OOP方法,因为存在其他与类型相关的问题,例如方法使用的状态没有精确的子类型。
使用observable
或makeObservable
时,Typescript中应该没有错误
这都是有效的代码:
import { makeAutoObservable, observable } from "mobx"
interface MyObject {
name: string
age: number
}
const obj1 = { name: "Uldis", age: 35 }
const make: MyObject = makeAutoObservable(obj1)
const obj1Observable: MyObject = observable(obj1)
function doStuff(obj: MyObject) {}
doStuff({ name: "Uldis", age: 35 })
doStuff(make)
doStuff(obj1Observable)
我看到了两种可能的解决方案:
- 使用盒装可观察
import { observable, IObservableValue } from "mobx";
interface MyObject {
name: string;
age: number;
}
const obj1 = { namee: "Uldis", age: "35" };
type MyObjectObservable = IObservableValue<MyObject>;
const obj1Observable: MyObjectObservable = observable.box(obj1);
obj1Observable.get(); // returns MyObject
- 添加您自己的品牌
Observable
类型,以避免使用附加对象进行包装
//customObservable.ts
import {observable as observableImpl} from 'mobx'
const mobx = Symbol('mobx');
export type Observable<T> = T & { [K in typeof mobx]: never };
export const observable = <T extends object>(obj: T): Observable<T> => {
return observableImpl(obj) as Observable<T>;
};
import { observable, Observable } from "./customObservable";
import { observable as originalObservable} from "mobx";
interface MyObject {
name: string;
age: number;
}
const obj1 = { namee: "Uldis", age: "35" };
type MyObjectObservable = Observable<MyObject>;
const obj1Observable: MyObjectObservable = observable(obj1);
const obj2Observable: MyObjectObservable = originalObservable(obj1); // compile-time error
obj1Observable.name; //string
obj1Observable.age; //number
仔细研究后,我提出了这个解决方案:
import { makeObservable,IObservableValue } from "mobx"
type MyObservable=IObservableValue<{name:string}>
const obj = makeMyObservable({ name:'Johny' })
const obj2 = {name:'Johny'}
function makeMyObservable<T extends Record<string,any>>(val:T){
return makeObservable(val) as unknown as IObservableValue<T>
}
function onlyMyObservable(val:MyObservable){
return val
}
onlyMyObservable(obj)
onlyMyObservable(obj2) // error
TS游乐场