如何根据Typescript中的接口键入key:reducerFunctions的对象
考虑以下接口:如何根据Typescript中的接口键入key:reducerFunctions的对象,typescript,generics,Typescript,Generics,考虑以下接口: interface TestState { a: number; b: string; } 我正在尝试编写一个泛型类型,指定对象必须: 包含与提供的接口相同的键(例如TestState) 对于每个键,提供一个reducer函数的值,将TestState中指定的类型作为状态本身的类型 例如,这样做的对象如下所示: const test: StateSlices<TestState> = { a: (state: number, action: any)
interface TestState {
a: number;
b: string;
}
我正在尝试编写一个泛型类型,指定对象必须:
- 包含与提供的接口相同的键(例如TestState)
- 对于每个键,提供一个reducer函数的值,将TestState中指定的类型作为状态本身的类型
const test: StateSlices<TestState> = {
a: (state: number, action: any) => state,
b: (state: string, action: any) => state,
};
我不知道如何正确地输入这个,并且已经试了一整天想找到一种方法,但是没有运气。最终,我希望能够为动作和状态指定关联的类型,但我将动作保留为“any”,因为我甚至无法使状态工作
任何帮助都将不胜感激
编辑
另外一个问题是,如果我试图将我不同的状态片段与特定的操作关联起来,那么最好的方法是什么
例如:
const test: StateSlices<TestState, keyof TestState> = {
a: (state: number, action: "ADD" | "SUBTRACT") => state,
b: (state: string, action: "TO_LOWERCASE" | "TO_UPPERCASE") => state,
};
const测试:状态片={
答:(状态:数字,动作:“加”|“减”)=>状态,
b:(state:string,action:“TO_小写”|“TO_大写”)=>state,
};
将TestState的切片“a”与其关联的操作关联的最佳方法是什么,这样会引发错误:
const test: StateSlices<TestState, keyof TestState> = {
a: (state: number, action: "TO_LOWERCASE" | "SUBTRACT") => state,
b: (state: string, action: "SUBTRACT" | "TO_UPPERCASE") => state,
};
const测试:状态片={
答:(状态:数字,动作:“TO_LOWERCASE”|“SUBTRACT”)=>状态,
b:(状态:字符串,动作:“减法”|“到_大写”)=>状态,
};
再次感谢。使用映射类型:
interface TestState {
a: number;
b: string;
}
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: any) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};
接口测试状态{
a:数字;
b:弦;
}
类型statesticles={
[K in keyof T]:(状态:T[K],动作:any)=>T[K]
}
常量测试:状态切片={
答:(状态,动作)=>状态,
b:(状态,动作)=>状态,
};
附录1:至于问题的第二部分,您可以使用条件类型根据您的状态类型获得所需的操作。它可以工作,但不能很好地扩展
interface TestState {
a: number;
b: string;
}
type GetAction<T> =
T extends number
? "ADD" | "SUBTRACT"
: T extends string
? "TO_LOWERCASE" | "TO_UPPERCASE"
: never;
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: GetAction<T[K]>) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};
接口测试状态{
a:数字;
b:弦;
}
类型GetAction=
T扩展数字
? “加”|“减”
:T扩展字符串
? “TO_小写”|“TO_大写”
:从不;
类型statesticles={
[K in keyof T]:(状态:T[K],操作:GetAction)=>T[K]
}
常量测试:状态切片={
答:(状态,动作)=>状态,
b:(状态,动作)=>状态,
};
附录2您也可以使用此技术:
interface TestState {
a: number;
b: string;
}
interface Actions {
a: "ADD" | "SUBTRACT";
b: "TO_LOWERCASE" | "TO_UPPERCASE";
}
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: K extends keyof Actions ? Actions[K] : never) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};
接口测试状态{
a:数字;
b:弦;
}
接口动作{
a:“加”|“减”;
b:“TO_小写”|“TO_大写”;
}
类型statesticles={
[K in keyof T]:(状态:T[K],动作:K扩展动作的键?动作[K]:从不)=>T[K]
}
常量测试:状态切片={
答:(状态,动作)=>状态,
b:(状态,动作)=>状态,
};
谢谢!作为奖励,您将如何将每个州的各个部分与特定的行动类型相关联?请首先详细说明每个
行动的所需类型。好的,我将编辑问题,谢谢。我刚刚更新了问题,非常感谢您提供的任何帮助,但非常感谢您的回答,我将其标记为已完成,希望有帮助!
interface TestState {
a: number;
b: string;
}
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: any) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};
interface TestState {
a: number;
b: string;
}
type GetAction<T> =
T extends number
? "ADD" | "SUBTRACT"
: T extends string
? "TO_LOWERCASE" | "TO_UPPERCASE"
: never;
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: GetAction<T[K]>) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};
interface TestState {
a: number;
b: string;
}
interface Actions {
a: "ADD" | "SUBTRACT";
b: "TO_LOWERCASE" | "TO_UPPERCASE";
}
type StateSlices<T> = {
[K in keyof T]: (state: T[K], action: K extends keyof Actions ? Actions[K] : never) => T[K]
}
const test: StateSlices<TestState> = {
a: (state, action) => state,
b: (state, action) => state,
};