mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
79 lines (70 loc) • 1.98 kB
text/typescript
import { failure } from "../utils"
import { registerDefaultStandardTypeResolvers } from "./registerDefaultStandardTypeResolvers"
import type { AnyStandardType, AnyType } from "./schemas"
import { isLateTypeChecker, LateTypeChecker, TypeChecker } from "./TypeChecker"
/**
* @internal
*/
export type StandardTypeResolverFn = (value: any) => AnyStandardType | undefined
const standardTypeResolvers: StandardTypeResolverFn[] = []
/**
* @internal
*/
export function registerStandardTypeResolver(resolverFn: StandardTypeResolverFn) {
standardTypeResolvers.push(resolverFn)
}
function findStandardType(value: any): AnyStandardType | undefined {
registerDefaultStandardTypeResolvers()
for (const resolverFn of standardTypeResolvers) {
const tc = resolverFn(value)
if (tc) {
return tc
}
}
return undefined
}
/**
* @internal
*/
export function resolveTypeChecker(v: AnyType | TypeChecker | LateTypeChecker): TypeChecker {
let next: TypeChecker | LateTypeChecker = v as any
while (true) {
if (next instanceof TypeChecker) {
return next
} else if (isLateTypeChecker(next)) {
next = next()
} else {
const tc = findStandardType(v)
if (tc) {
return resolveTypeChecker(tc)
}
throw failure("type checker could not be resolved")
}
}
}
/**
* @internal
*/
export function resolveStandardTypeNoThrow(
v: AnyType | TypeChecker | LateTypeChecker
): AnyStandardType | undefined {
if (v instanceof TypeChecker || isLateTypeChecker(v)) {
return v as any
} else {
const tc = findStandardType(v)
if (tc) {
return tc
}
return undefined
}
}
/**
* @internal
*/
export function resolveStandardType(v: AnyType | TypeChecker | LateTypeChecker): AnyStandardType {
const tc = resolveStandardTypeNoThrow(v)
if (tc) {
return tc
}
throw failure("standard type could not be resolved")
}