如何使用非OOP方法对MobX可观察对象进行类型注释



请考虑以下示例:

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方法,因为存在其他与类型相关的问题,例如方法使用的状态没有精确的子类型。

使用observablemakeObservable时,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)

我看到了两种可能的解决方案:

  1. 使用盒装可观察
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
  1. 添加您自己的品牌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游乐场

最新更新