typescript 如何定义没有特定字段的对象的类型,甚至没有设置为undefined?

rlcwz9us  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(275)

我有这样的代码:

interface BaseType {
    baseField: string;
}

function combine<T extends Object>(base: BaseType, addition: T) {
    if('baseField' in addition)
        throw new Error('addition should not have baseField');
    return {...base, ...addition};
}

const myBase : BaseType = {
    baseField: "xyz"
}

const myAddition = {
    otherField: 123
}

const ret = combine(myBase, myAddition);
// --> ret = { baseField: "xyz", otherField: 123}
console.log(JSON.stringify(ret))

如果combine()addition参数导致baseField被覆盖,我想使用TypeScript的类型定义功能来触发IDE/编译器警告/错误。在我目前的设置中,我只在已经“太晚”的时候才获得有关它的信息,即。在运行时期间。
我尝试了像Typescript type with prohibited properties names这样的问题的答案中描述的解决方案。虽然solutions like this在许多情况下都很好,但它们不适用于addition.baseField = undefined。例如,这不会触发任何警告:

interface BaseType {
    baseField: string;
}

type RestrictionType = Object & {
    specialField?: never
}

function combine<T extends RestrictionType>(base: BaseType, addition: T) {
    return {...base, ...addition};
}

const myBase : BaseType = {
    baseField: "xyz"
}

const myAddition = {
    otherField: 123,
    baseField: undefined // set baseField explicitly to undefined
}

const ret = combine(myBase, myAddition); // no warning because undefined actually seems to match the "never" type
// --> ret = { otherField: 123 } // baseField got removed
console.log(JSON.stringify(ret))

那么,我如何指定一个对象的类型,其中一个特定名称的字段不能设置,甚至不能设置为undefined
这里有一个指向TypeScript Playground的链接。

swvgeqrz

swvgeqrz1#

据我所知,默认情况下,可选属性与undefined属性完全相同; TypeScript的类型系统根本不区分这两者。
TypeScript确实提供了一个选项--exactOptionalPropertyTypes来改变这一点。使用该选项,您的代码会根据需要抛出警告(Playground链接)。
不幸的是,根据我有限的经验,启用--exactOptionalPropertyTypes可能需要进行相当大的代码更改。在我的理想世界中,TypeScript会让你使用opt in to this behavior for specific types。然而,这似乎是一个相当利基的要求。

相关问题