【问题标题】:TypeScript : avoid extra propertiesTypeScript:避免额外的属性
【发布时间】:2020-09-09 14:34:05
【问题描述】:

感谢您查看我的打字稿问题。

为了简单起见,我对打字稿“多余的属性检查”行为有疑问。我想确保 TypeScript 不接受具有额外属性的对象。

OFC 在我的简单界面示例中,我可以简单地选择可用数据,但我有很多属性,我想避免在运行时过滤它们,有什么办法吗?

在这里你可以找到我为这个主题制作的示例代码:

TypeScript Playground

type LayoutType {
    margin: number;
}

const badData = {
    margin: 23,
    padding: 23,
}

function func(param: LayoutType) {
    console.log(param);
    // Here I want to use property being sure param only contains LayoutType property
}

// OK
func({ margin: 42 })
// OK : padding is detected as unwanted property
func({ margin: 42, padding: 32 })
// KO : bad data shouldn't fit
func(badData)

/* SAME */

// OK : padding is detected as unwanted property
const test1: LayoutType = { margin: 42, padding: 32 };
// KO : bad data shouldn't fit
const test2: LayoutType = badData;

提前致谢

【问题讨论】:

  • 不确定你想要什么,因为你已经收到了一个错误Argument ... is not assignable。如果你想删除不需要的属性,你必须明确地这样做,TS 不会改变你的程序的行为......

标签: typescript


【解决方案1】:

听起来你想要一个Exact 类型。 Typescript 没有自带,但很容易制作:

type Exact<A, B> = A extends B
  ? B extends A
    ? A
    : never
  : never

这基本上说如果和A extends B B extends A 那么类型是相同的,既不是另一个的子集也不是另一个的超集。所以它应该允许该类型通过。如果它们不相同,则类型为 never,这会阻止该类型被允许。

现在你只需要使你的函数泛型,并将该参数强制为正确的类型:

function func<T>(param: Exact<T, LayoutType>) {
    console.log(param);
}
func(badData)
// Argument of type '{ margin: number; padding: number; }'
//   is not assignable to parameter of type 'never'.

Playground

更多相关阅读请点击Typescript issue #12936


最后,对象字面量不起作用但对象变量起作用的原因是该字面量是为特定类型构造的。 Typescript 无法知道额外的属性,因为这些属性没有类型信息。所以打字稿程序不能使用这些属性,因为它们没有被声明为存在。

然而,当对象是一个变量并且额外的属性是已知的,那么它就是一个独立但兼容的类型。额外的属性可能不会在只接受窄类型的函数中使用,但在其他知道更宽类型的代码中可以使用属性

这就是它有效的原因:

const obj1 = { a: 1, b: 2 }
const obj2: { a: number } = obj1

console.log(obj1.b) // b can still be accessed

但这不是:

const obj1: { a: number } = { a: 1, b: 2 }
//                                  ^ type error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-24
    • 2020-02-10
    • 2012-01-26
    • 2016-12-21
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多