首先,我想了解为什么一些 TypeScript 定义文件以两种形式给出(我将尝试通过lodash示例来展示这一点)。
第一个是“基于命名空间”(来自@types/lodash定义):
export = _;
export as namespace _;
declare var _: _.LoDashStatic;
declare namespace {
(...)
}
Run Code Online (Sandbox Code Playgroud)
第二个是“基于模块”(来自typings模块定义):
declare module 'lodash' {
var _: _.LoDashStatic;
namespace _ {
(...)
}
export = _;
}
Run Code Online (Sandbox Code Playgroud)
同一个库的两个定义源显示了不同的方法。这里的权衡是什么,为什么一些来自@types/...源代码的类型在第二个中优先考虑?
我在将“基于命名空间”的定义与位于我的项目范围之外的共享代码一起使用时遇到了一些问题,因此我更喜欢“基于模块”的定义。好了,第二步来了。我想标准化这些定义并且只使用@types/...源,但是当我得到“基于命名空间”的定义(比如lodash)时,我想编写一些自定义定义(尽可能短),它将在“基于模块”中重新导出该命名空间道路。
我试过这样的事情:
declare module "lodash" {
import * as x from "lodash";
var _: x.LoDashStatic;
namespace _ {}
export = _;
}
Run Code Online (Sandbox Code Playgroud)
这当然不起作用(除了不再有cannot find module...错误),但我认为几乎显示了我在这里想要完成的工作。我的目标是使用声明的命名空间@types/lodash/index.d.ts并custom_typings/lodash.d.ts …
我想TRecursive基于我的数据接口创建递归的泛型类型IOne,ITwo并且IThree如下所示相关.
结果类型TRecursive<IOne>应具有与IOne不同值类型相似的关系boolean,例如下面的示例.
interface IOne {
pk: number;
name: string;
two: ITwo;
}
interface ITwo {
pk: number;
name: string;
three: IThree;
}
interface IThree {
pk: number;
name: string;
}
type TRecursive<T> = {
[P in keyof T]?: TRecursive<T[P]> | boolean;
};
const test: TRecursive<IOne> = {
pk: true,
name: true,
two: {
pk: true,
name: true,
anything: true, // type error as expected
three: { …Run Code Online (Sandbox Code Playgroud) 我创建了一些工厂功能,为我提供简单(或更高级)的减速器.例如(简单的一个 - 基于动作类型将RequestState常量设置为值):
export const reduceRequestState = (requestTypes: RequestActionTypes) =>
(state: RequestState = RequestState.None, action: Action): RequestState => {
switch (action.type) {
case requestTypes.start:
return RequestState.Waiting;
case requestTypes.success:
return RequestState.Success;
case requestTypes.error:
return RequestState.Error;
case requestTypes.reset:
return RequestState.None;
default:
return state;
}
};
Run Code Online (Sandbox Code Playgroud)
使用这些工厂的功能和combineReducers从redux我可以撰写他们入处理大部分的我不经意的动作功能齐全的减速.这给了我可读的代码,并防止我犯了愚蠢的错误.
工厂适用于常见操作,但是当我需要添加一些自定义行为(对于操作类型)时应该显着修改商店的某些部分,我想编写一个自定义部分的reducer,它将为我处理该操作.我们的想法是以迭代方式组合reducer,combineReducers但是对于一个数组.这样我就可以使用我的工厂创建reducer,然后将它与我的自定义reducer结合起来,处理一些特定的操作.然后combineReducers,数组将调用第一个数组,识别没有任何更改,并调用第二个(自定义)数组来处理操作.
我一直在寻找一些解决方案并且发现它redux-actions但不太喜欢它将动作和减速器联系起来的方式,这使得语义与我以前的方法略有不同.也许我没有得到它,但最终我喜欢看到我的减速机被写成纯函数.
我正在寻找一些能给我指路的提示.是否有任何图书馆或项目使用任何类型的高阶减速器并以某种方式组合它们?如上所述,组成减速器是否有任何缺点?