javascript - typescript 中映射的定义列表中的动态键名称

标签 javascript typescript typescript-typings

我正在尝试在 typescript 中定义 type.. 它应该接受至少一个键值(在定义的列表中)。如果数据在列表中至少有一个定义的键,则剩余应该是可选的。

我们有什么办法可以在 typescript 中做到这一点。

type values = 'a' | 'b' | 'c' | 'd';
type data<T extends string, K> = Record<T, K>;

// current output:
const d:data<values, string> = {
  'a': 'sample text',
  'b': 'b sample text',
  'c': 'c sample text'
};

// Expecting output
const d:data<values, string> = {
  'a': 'sample text'
}

在上面的示例中,d 需要values 中的每个键。我确实尝试过 partial 它使所有值都是可选的。

我的意图是传入的数据应该至少有一个来自 valueskey

注意: 值非常动态或具有更长的列表。

最佳答案

您可以通过使用 Partial<T> 交叉映射类型来单独要求每个属性来做到这一点

type AtLeastOne<T> = {
    [K in keyof T]: {
        [K2 in K]: T[K]
    }
}[keyof T] & Partial<T>

工作原理:

  1. 遍历所提供记录中的所有键,并将结果记录中的类型设置为仅具有该键的对象 { [K in keyof T] ... }
  2. 获取映射类型中所有元素的并集[keyof T]
  3. 将并集与 Partial<T> 相交要求任何其他提供的属性是正确的类型

演示:Playground

type AtLeastOne<T> = {
    [K in keyof T]: {
        [K2 in K]: T[K]
    }
}[keyof T] & Partial<T>

type Data<K extends string, T> = AtLeastOne<Record<K, T>>

type Keys = 'a' | 'b' | 'c' | 'd'

type Result = Data<Keys, string>

const x: Data<Keys, string> = {
    a: '' // ok
}

const y: Data<Keys, string> = {} // error

关于javascript - typescript 中映射的定义列表中的动态键名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59003078/

相关文章:

reactjs - 找不到名称 'fetch'

typescript - 如何将一个方法的签名复制到另一个方法?

javascript - 强制检查 dirtyforms.js

Javascript:通过 .style 在悬停时设置元素颜色

javascript - JQuery 递归函数?

javascript - 按需导入模块组件

typescript - 在 TypeScript 中推断函数参数

javascript - 类型 'Query' 的对象不可 JSON 序列化

javascript - 黑白 React Typescript、React JavaScript 和 React Native 的区别?

Angular - 将 Observable<number> 转换为数字