面试题答案
一键面试设计思路
- 泛型定义:
- 为每个选择器函数的输入定义一个泛型
S
,表示全局状态类型。 - 为每个选择器函数的返回值定义不同的泛型,例如
R1
,R2
, ...,Rn
,表示部分状态类型。 - 为转换函数的返回值定义一个泛型
Result
。
- 为每个选择器函数的输入定义一个泛型
- 类型约束:
- 确保每个选择器函数接受类型为
S
的全局状态对象。 - 确保转换函数接受的参数类型与选择器函数的返回类型一一匹配。
- 确保
createSelector
函数返回的结果类型与转换函数的返回类型Result
匹配。
- 确保每个选择器函数接受类型为
代码实现
type Selector<S, R> = (state: S) => R;
function createSelector<S, R1, R2, Result>(
selector1: Selector<S, R1>,
selector2: Selector<S, R2>,
transform: (arg1: R1, arg2: R2) => Result
): (state: S) => Result;
function createSelector<S, R1, R2, R3, Result>(
selector1: Selector<S, R1>,
selector2: Selector<S, R2>,
selector3: Selector<S, R3>,
transform: (arg1: R1, arg2: R2, arg3: R3) => Result
): (state: S) => Result;
// 可以继续扩展更多选择器的重载
function createSelector<S, R1, R2, Result>(
selector1: Selector<S, R1>,
selector2: Selector<S, R2>,
transform: (arg1: R1, arg2: R2) => Result
): (state: S) => Result {
return (state: S) => {
const result1 = selector1(state);
const result2 = selector2(state);
return transform(result1, result2);
};
}
在上述代码中:
- 首先定义了
Selector
类型,它是一个函数类型,接受一个全局状态S
并返回一个部分状态R
。 - 然后使用函数重载定义了
createSelector
函数,不同的重载对应不同数量的选择器函数。每个重载都确保选择器函数的输入类型为S
,并且转换函数的输入类型与选择器函数的返回类型匹配。 - 最后实现了
createSelector
函数,它返回一个新的函数,该函数接受全局状态S
,调用每个选择器函数并将其结果传递给转换函数,最终返回转换函数的结果。