首页 > 解决方案 > TypeScript 对象属性需要重复定义

问题描述

我是 TypeScript 的新手,正在努力尝试创建一个函数,该函数正确地为对象内的可选对象设置默认值。

当我尝试定义参数中的所有内容时,我收到一个错误,即其中一个属性(options.target.value)可能未定义。当调用该函数并将其约束到需要该属性的接口时,可以选择提供所讨论的对象,或者如果未提供该对象,则将使用也使用相同接口的函数进行设置。

令人困惑的是,我提供了一个不满足 TypeScript 的默认 options.target,但是当我检查 !options.target 并使用相同的 getTarget() 函数提供它时,TypeScript 很高兴。这只是 TypeScript 中的一个错误,还是我对如何设置默认对象属性有误解?

谢谢!

function getTarget(): Target {
    const target: Target = page.targets[0];
    console.log('target._id = ', target._id); //always OK, TS does not mark this as possibly undefined.
    return target;
}


function test(
    options: {target?: Target;} //when provided, must have a 'value' property
           = {target: getTarget()} //if not provided, default always has a 'value' property
) {
    if (!options.target) { options.target = getTarget(); } //without this, I get the TS error below
    console.log('options.target', options.target); //always OK
    console.log('options.target', options.target.value); //ERROR: TS2532 Object is possibly 'undefined' if required line above commented out
}

标签: typescript

解决方案


为嵌套值提供默认参数可能有点棘手。

让我们分解一下这个函数签名的含义:

function test(
    options: { target?: Target } = { target: getTarget() }
)

用简单的英语,test接受一个可选参数optionsoptions是一个对象,它具有一个名为 的可选属性target。如果省略该参数,则将使用一个肯定有目标的默认值。

这意味着将允许以下函数调用:

test() // default object used
test({}) // default object not used, target omitted
test({ target: someTarget }) // default object not used, target present.

这种test({})情况会target在您的函数中留下未定义的,因为您没有提供目标,并且您已经阻止使用默认参数。

这里的解决方法是使目标不是可选的:

function test(
    options: { target: Target } = { target: getTarget() }
) {
    console.log('options.target', options.target.value);
}

test() // works
test({ target: { _id: 123, value: 'test' }}) // Works

test({}) // Error

或者根本不使用默认参数而自己做。

function test(
    options?: { target?: Target }
) {
    const target = options?.target ?? getTarget()
    console.log('options.target', target.value);
}

test() // Works
test({ target: { _id: 123, value: 'test' } }) // Works
test({}) // Works

操场


推荐阅读