简体   繁体   English

Typescript接口模板使用keyof查找

[英]Typescript interface template using keyof lookup

I want something like我想要类似的东西


interface Operation<T, K extends keyof T> {
  key: keyof T;
  operation: 'add' | 'remove';
  value: T[K];
}

but without requiring to pass the K as a template;但不需要将K作为模板传递; basically, I want to be able to do:基本上,我希望能够做到:

interface User {
  name: string;
  age: number;
}

// this is valid
const operation: Operation<User> = {
  key: 'name',
  operation: 'add',
  value: 'the value',
}
// this is valid
const operation: Operation<User> = {
  key: 'age',
  operation: 'add',
  value: 123,
}

// this is not valid
const operation: Operation<User> = {
  key: 'age',
  operation: 'add',
  value: '123',  // type is wrong, should be number
}

How do I do this?我该怎么做呢?

Personally we can if we refine the way of creating the object by using function.如果我们使用 function 改进创建 object 的方法,就个人而言,我们可以。 The idea is like below:这个想法如下:

First of all, create the type getting value type of any property:首先,创建类型获取任何属性的值类型:

type ValueType<T, K> = K extends keyof T ? T[K] : never;

Then define Operation type:然后定义Operation类型:

type Operation<T, K> = {
  key: K
  operation: 'add' | 'delete'
  value: ValueType<T, K>
}

Now the key thing is here to define the build function instead of create the object directly since we're keen to read the argument:现在关键是在这里定义构建 function 而不是直接创建 object 因为我们热衷于阅读参数:

type BuildOperation<T> = <K>(arg: K) => (arg: Operation<T, K>) => Operation<T, K>


function build<T>(): BuildOperation<T> {
  return (key) => (props) => ({
    key,
    ...props,
  });  
}

Finally, we can use our function by setting key as const to make sure Typescript won't infer as string:最后,我们可以通过将 key 设置as const来使用我们的 function 以确保 Typescript 不会推断为字符串:

type User = { name: string; age: number }

const obj = build<User>()('age' as const)({
  key: 'age',
  value: 20, // It will hint you this is number
  operation: 'add',
});
interface Operation<T, K extends keyof T> {
  operation: "add" | "remove";
  value: T[K];
}

interface User {
  name: string;
  age: number;
}

// this is valid
const operation1: Operation<User, "name"> = {
  operation: "add",
  value: "the value",
};

// this is valid
const operation2: Operation<User, 'age'> = {
  operation: "add",
  value: 123,
};

// this is not valid
const operation3: Operation<User, 'age'> = {
  operation: "add",
  value: "123", // type is wrong, should be number
};

I recommend use keyof .我建议使用keyof but, I agree comments.但是,我同意评论。 Why is it needed?为什么需要它? it not work on runtime application.它不适用于运行时应用程序。 It just check when it is compiled.它只是检查它何时编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM