TypeScript — 如何根据动态键推断键值类型

时间:2020-12-18 23:26:19

标签: typescript use-reducer

假设我有一个带有如下接口的状态对象:

n = 10000000    
set.seed(1)
x = rnorm(n)
y = rnorm(n)
 microbenchmark::microbenchmark(my_rstudent(x, y),rstudent(lm(y~x)),unit="relative", times = 10)
Unit: relative
                expr      min       lq     mean  median       uq      max neval
   my_rstudent(x, y) 1.000000 1.000000 1.000000 1.00000 1.000000 1.000000    10
 rstudent(lm(y ~ x)) 1.603652 1.603881 1.534455 1.58802 1.560724 1.305315    10

microbenchmark::microbenchmark(my_rstudent(x, y),rstudent(lm(y~x)), times = 10)
Unit: seconds
                expr      min       lq     mean   median       uq      max neval
   my_rstudent(x, y) 1.584408 1.619822 1.727310 1.658917 1.757311 2.213203    10
 rstudent(lm(y ~ x)) 2.458445 2.619609 2.705212 2.696705 2.776588 2.949799    10

我想生成一个reducer函数来改变这种状态下的值。我很想拥有一个名为 interface IState { car_brand: string; year: number; + many other properties with various types } action,它可以处理更改 state 中的任何值。然后我会像这样输入那个动作:

set_value

现在我的问题是如何键入 enum ACTION_TYPE { set_value = ‘set_value’, } type IAction = { type: ACTION_TYPE.set_value; payload: { ??? }; }; 以便它可以处理来自 IState 的任何键,然后正确推断所需的值类型?在伪代码中,我会寻找这样的东西:

payload

如何在 TypeScript 中正确编写该负载类型?

1 个答案:

答案 0 :(得分:2)

我会使用 Typescript 实用程序类型 Partial

像这样:

type IAction =
{
    type: ACTION_TYPE.set_value;
    payload: Partial<IState>
};

这意味着 payload 具有相同类型的 IState,但所有属性都转换为可选。

这样就可以了,并且正确地将 year 的类型限制为 number

interface IState 
{
    car_brand: string;
    year: number;
}

{
   type: ACTION_TYPE.set_value,
   payload: {
      year: 1997 // Would produce an error if you changed it to a string
   }
}

但这会导致错误,因为 foo 在您的状态类型中不存在:

interface IState 
{
    car_brand: string;
    year: number;
}

{
   type: ACTION_TYPE.set_value,
   payload: {
      foo: "baz"
   }
}