类型检查选项套件中的介绍 exactOptionalPropertyTypes
:
在JavaScript中,读取对象上缺少的属性会产生未定义的值。还可以使用未定义值的实际属性。JavaScript中的许多代码倾向于以同样的方式处理这些情况,因此最初TypeScript只是将每个可选属性解释为用户在类型中编写了未定义的内容。例如, 接口人{名称:字符串,年龄?:数字;} 被认为相当于 接口人{名称:字符串,年龄?:数字,未定义;} 这意味着用户可以显式地编写未定义的内容来代替年龄。 const p: Person ={ name:"Daniel",age: undefined,//这在默认情况下是可以的。}; 因此,默认情况下,TypeScript不区分值未定义的当前属性和缺少的属性。虽然大多数情况下这是可行的,但并非JavaScript中的所有代码都有相同的假设。函数和操作符,如Object.assign、Object.keys、对象扩展({ ...obj })和for-in循环的行为不同,取决于对象上是否存在属性。在我们的Person示例中,如果在age属性的存在很重要的上下文中观察到age属性,这可能会导致运行时错误。在TypeScript 4.4中,新标志 //与'exactOptionalPropertyTypes‘在: const : Person ={ name:"Daniel",年龄:未定义,//错误!未定义的不是一个数字}; 这个标志不是--严格的家庭的一部分,如果你想要这样做的话,需要明确地打开它。它还要求启用我们将对DefinitelyTyped和其他定义进行更新,以尽可能简单地进行转换,但您可能会遇到一些摩擦,这取决于代码的结构。
如果启用此功能标志,则我的代码
function f(input: OptionsInterface): void {
const target: PacketInterface = {
cmd: 'connect',
clientId: input.clientId,
protocolVersion: input.protocolVersion,
};
console.log(target);
};
给出错误:
Type '{ cmd: "connect"; clientId: string; protocolVersion: 4 | 5 | 3 | undefined }' is not assignable to type 'PacketInterface' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Types of property 'protocolVersion' are incompatible.
Type '4 | 5 | 3 | undefined' is not assignable to type '4 | 5 | 3'.
“目标”接口是PacketInterface:
export interface PacketInterface {
cmd: 'connect'
clientId: string
protocolVersion?: 4 | 5 | 3
}
所提供的对象的接口是``PacketInterface‘的一个超集:
export interface OptionsInterface {
cmd: 'connect'
clientId: string
protocolVersion?: 4 | 5 | 3
clean?: boolean
keepalive?: number
username?: string
password?: Buffer
}
我创建了MCVE来演示这一点:TS游乐场MCVE。
我有一个超集'options‘对象,它为基于依赖关系的接口的子集'packet’对象提供值。在'packet‘接口中,可选值使用?:
,这意味着如果我提供undefined
作为值,TypeScript现在会抱怨。
虽然预计会出现错误,但解决方案尚不清楚。当前无法更新依赖项的类型。我只需禁用exactOptionalPropertyTypes
功能标志就可以消除错误,但这会移除类型检查的级别。启用此功能标志时,如何使用未定义的值创建对象?类型强制?以某种方式使用接口来检查options
对象中的值?我不想手动检查“options”对象中的每个值,以便在将其添加到我正在创建的“packet”类型对象之前查看它是否存在。
发布于 2022-01-20 23:54:54
您必须拥有未定义的密钥。因此,您可以使用三元或扩展运算符:
interface foo {
x?: string;
y?: number;
z?: number;
}
interface bar {
x?: string;
}
function f(input: foo): void {
const zoom: bar = input.x ? { 'x': input.x } : {};
/// or
const zoom: bar = { ...input }
console.log(zoom);
};
https://stackoverflow.com/questions/70794241
复制相似问题