一种方法是改进你收到的任何东西的类型,直到它符合你想要的形状。通常,我会制作一些基本的优化函数,并使用它们来构建更大的优化。
(
Try
)
// From libdef
type Locals = {
[name: string]: mixed;
}
// Populated data
const locals: Locals = {
version: 1.2,
resources: {
a: "abc",
b: "def"
}
};
// The type you want
type MyLocals = {
version: number,
resources: {
// maybe this one is a map? idk
[string]: string
}
}
// Some basic refinement functions
const refineString = (x: mixed): string => {
if (typeof x === 'string') {
return x
}
throw new Error("Not a string")
}
const refineNumber = (x: mixed): number => {
if (typeof x === 'number') {
return x
}
throw new Error("Not a number")
}
const refineObj = (x: mixed): {[string]: mixed} => {
if (x instanceof Object) {
return x
}
throw new Error("Not an object")
}
// More type-specifc refinement functions
const refineResources = (x: mixed): $ElementType<MyLocals, 'resources'> => {
const anObj = refineObj(x)
return Object.keys(anObj)
.reduce((acc, k) => Object.assign(acc, { [k]: refineString(anObj[k]) }), {})
}
const refineMyLocals = (x: mixed): MyLocals => {
const {version, resources} = refineObj(x)
return {
version: refineNumber(version),
resources: refineResources(resources)
}
}
// Now use them to assert a type
const myLocals: MyLocals = refineMyLocals(locals)
const version: number = myLocals.version;
const resources: {[string]: string} = myLocals.resources;
或者,如果libdef在
flow-typed
文件夹,进去换一下libdef。它将使该类型特定于您的项目,但如果您不需要
[name: string]: mixed
在代码中键入其他地方。