【问题标题】:How to enforce consistent type within objects (Typescript)?如何在对象(Typescript)中强制执行一致的类型?
【发布时间】:2022-01-11 04:03:42
【问题描述】:

我已经做到了这一点:这似乎有效

function test<types extends Record<string,any>>(dict: dictionary<types>){}

type dictionary<types extends Record<string, any>> = {
  [key in keyof types]: {
    bar?: types[key];
    foo?: (value:types[key])=>true;
  };
};

test({
 key1:{
  bar: 2,
  foo: (input:number)=>true,
 },
 key2:{
  bar: 'hello'
  foo: (input: number)=>true, // Error! "input" needs to be string
 }
})


但是! 我还需要对dict 参数的泛型类型引用。而且由于某种原因,这不起作用


function test2<
  types extends Record<string,any>,
  dictionary extends dictionary2<types> // <-- Added a generic type
>(dict: dictionary){}

// Same as above
type dictionary2<types extends Record<string, any>> = {
  [key in keyof types]: {
    bar?: types[key];
    foo?: (value:types[key])=>true;
  };
};

// Same as above
test2({
 key1:{
  bar: 2,
  foo: (input: number)=>true,
 },
 key2:{
  bar: 'hello', 
  foo: (input:number)=>true,// Should be an Error (but isn't)! "input" needs to be string
 }

Playground link

【问题讨论】:

  • 请考虑this 示例。 This 是相关问题。有缺点。您需要使用方法,因为它们是双变量的。让喵知道它是否有效。如果您预先知道自己的价值观,则可以使用this 示例。但是,最好的方法是使用 builder 函数。它简单、易读且安全
  • 构建器示例-> here)

标签: javascript typescript typescript-typings typescript-generics


【解决方案1】:

你可以这样做:

function test2<T extends Record<string, unknown>>(dict: Dictionary<T>) { }

type Dictionary<T> = {
  [key in keyof T]: {
    bar?: T[key];
    foo?: (value: T[key]) => true;
  };
}

// Same as above
test2({
  key1: {
    bar: 2,
    foo: (input: number) => true,
  },
  key2: {
    bar: 'hello',
    foo: (input: number) => true, // Actual error
  }
});

TypeScript playground

【讨论】:

  • 似乎有一个比我想象的更简单的解决方案。不错!
【解决方案2】:

更改推理范围,以便推断 types 并根据该推理而不是第二个类型参数键入 dict,即,

function test2<
  types extends Record<string,any>
>(dict: dictionary2<types>){}

工作场所here.

编辑:常规大写的用法示例

function test2<
  T,
>(dict: Dictionary<T>){

  type FullDictionary = Dictionary<T> // can't you just use this in your function?

}

type Dictionary<T extends Record<string, any>> = {
  [K in keyof T]: DictionaryEntry<T[K]>
}

type DictionaryEntry<T> = {
  bar?: T
  foo?: (value:T)=>true
}

test2({
 key1:{
  bar: 2,
  foo: (input: number)=>true,
 },
 key2:{
  bar: 'hello', 
  foo: (input:number)=>true
 }
})

【讨论】:

  • 如果我错了,请纠正我,但这与我目前拥有的代码相同,不是吗(即在我的问题顶部给出)
  • 哦,哈。但后来我想我对你的问题感到困惑。为什么不能只使用dictionary&lt;types&gt;?顺便说一句,为了便于阅读,通常使用大写类型编写此代码,例如:function test&lt;T extends Record&lt;string,any&gt;type Dictionary = 等。
  • 我需要一个对 dictionary 类型的通用引用来检查某些属性是否存在
  • 但是在任何你想使用泛型的地方,你不能只使用字典吗?我已经编辑了我的答案以显示我的意思。在我编辑的答案中,FullDictionary 不是给你你想要的吗?什么泛型类型参数允许你做你不能做的事情? (对不起,如果我很密集)
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2018-11-24
  • 2020-05-26
  • 1970-01-01
  • 2012-10-30
相关资源
最近更新 更多