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 从类型中选择一个键值对_Typescript_Typescript Generics - Fatal编程技术网

Typescript 从类型中选择一个键值对

Typescript 从类型中选择一个键值对,typescript,typescript-generics,Typescript,Typescript Generics,我有以下类型: type Example = { key1: number, key2: string } 我需要根据Exampletype创建类型,使之成为key:valuepair中的一个。当然,我在寻找通用的解决方案。以下是此类型应返回的内容: type Example2 = { ... }; const a: Example2 = { key3: 'a' } // incorrect const b: Example2 = { key1: 'a' } // incorrect

我有以下类型:

type Example = {
  key1: number,
  key2: string
}
我需要根据
Example
type创建类型,使之成为
key:value
pair中的一个。当然,我在寻找通用的解决方案。以下是此类型应返回的内容:

type Example2 = { ... };
const a: Example2 = { key3: 'a' } // incorrect
const b: Example2 = { key1: 'a' } // incorrect
const c: Example2 = { key2: 1 } // incorrect
const d: Example2 = { key1: 1 } // correct
const e: Example2 = { key2: 'a' } // correct
const f: Example2 = { key1: 1, key2: 'a' } // incorrect
我试着用这个:

type GetOne<T> = { [P in keyof T]: T[P] };
type Example2 = GetOne<Example>;
type GetOne={[P in keyof T]:T[P]};
类型Example2=GetOne;

但它返回所有属性和示例,其中
常量f
未按预期工作。

我们将生成所有可能性的并集:

type Example = {
   key1: number,
   key2: string
}

type PickOne<T> = { [P in keyof T]: Record<P, T[P]> & Partial<Record<Exclude<keyof T, P>, undefined>> }[keyof T]
type Example2 = PickOne<Example>;
const a: Example2 = { key3: 'a' } // incorrect
const b: Example2 = { key1: 'a' } // incorrect
const c: Example2 = { key2: 1 } // incorrect
const d: Example2 = { key1: 1 } // correct
const e: Example2 = { key2: 'a' } // correct
const f: Example2 = { key1: 1, key2: 'a' } // incorrect
类型示例={
关键1:数字,
键2:字符串
}
类型PickOne={[P in keyof T]:记录和部分}[keyof T]
类型示例2=PickOne;
常数a:Example2={key3:'a'}//不正确
常数b:Example2={key1:'a'}//不正确
常量c:Example2={key2:1}//不正确
常量d:Example2={key1:1}//正确
常数e:Example2={key2:'a'}//正确
常量f:Example2={key1:1,key2:'a'}//不正确
我们这样做的方式是,我们首先创建一个新类型,对于每个键,我们都有一个只包含该键的对象属性(暂时忽略
&Partial
)。例如,
{[P in keyof T]:Record}
将是:

type Example2 = {
    key1: Record<"key1", number>;
    key2: Record<"key2", string>;
}
类型示例2={
关键词1:记录;
键2:记录;
}
然后使用索引操作
[keyof T]
获得这个新类型中所有值的并集,因此我们得到
Record | Record

此类型将适用于除上一个测试之外的所有测试,在上一个测试中,您希望不允许来自原始类型的多个属性。由于多余属性检查处理联合类型()的方式,如果键存在于任何联合成分中,它将允许使用该键


为了解决这一问题,我们将
记录
与一个类型相交,该类型可选地包含其余属性(
排除
),但强制所有属性都
未定义

,也可以通过以下代码实现:

export type PickOne<T> = {
    [P in keyof T]?: Record<P, T[P]>
}[keyof T]

type Example = {
    key1: number;
    key2: string;
}

type Example2 = PickOne<Example>;

const a: Example2 = { key1: 1 } // correct
const b: Example2 = { key1: "1" } // incorrect - string cannot be assigned to number
const c: Example2 = { key2: 'a' } // correct
const d: Example2 = { key3: 'a' } // incorrect - unknown property
导出类型PickOne={
[P in keyof T]?:记录
}[keyof T]
类型示例={
键1:数字;
键2:字符串;
}
类型示例2=PickOne;
常数a:Example2={key1:1}//正确
常量b:Example2={key1:“1”}//不正确-无法将字符串分配给数字
常数c:Example2={key2:'a'}//正确
常量d:Example2={key3:'a'}//不正确-未知属性