Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何根据Typescript中的接口键入key:reducerFunctions的对象_Typescript_Generics - Fatal编程技术网

如何根据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,
};