简体   繁体   English

使用接口在typescript中键入匿名对象

[英]using a interface to type a anonymous object in typescript

I have a Interface IBase and a variable that contains a few other objects (in the sample i just added base for a better demonstration) 我有一个接口IBase和一个包含一些其他对象的变量(在示例中我刚添加了基础以便更好地演示)

interface IBase {
    height?:number;
    width?:number;
}

var element = {
    base: {

    }
}

How can I say that the object that the varable element.base has is from the type IBase? 我怎么能说可变元素.base所拥有的对象来自IBase类型? I know that I could create a type for the element variable that contains the types of base etc, but is that also a possibility to type that scenario without doing so. 我知道我可以为包含base等类型的元素变量创建一个类型,但是也可以在不这样做的情况下键入该场景。

Van den Brink's answer is good. Van den Brink的答案很好。 Just as a demo another option : 就像演示另一种选择:

var element = {
    base: <IBase> {

    }
}

This will give the desired intellisense as well : 这也将提供所需的智能感知:

在此输入图像描述

If you change the declaration of var element to the following it knows what base is: 如果将var元素的声明更改为以下内容,则它知道基数是什么:

var element: { base: IBase; } = {
    base: {
    }
}

Note: you can also create a new interface for it like this which makes it a bit more reusable: interface IElement { base: IBase; 注意:您也可以像这样为它创建一个新的接口,使其更具可重用性:interface IElement {base:IBase; } and then use it like here: var element: IElement = { base: {} } 然后像这里一样使用它:var element:IElement = {base:{}}

You have accidentally caused yourself a problem with your interface declaration. 您不小心导致自己的界面声明出现问题。 It is a subtle one that you will come across with structurally typed languages. 这是一个微妙的结构类型语言。

interface IBase {
    height?:number;
    width?:number;
}

Because all of the properties are optional, the interface is essentially {} . 因为所有属性都是可选的,所以接口基本上是{} ie any object satisfies this interface. 即任何对象都满足此接口。 That's too general to be useful in most cases. 在大多数情况下,这种做法太普遍了。

For example, it is perfectly acceptable to do this: 例如,这样做是完全可以接受的:

var x: IBase = {
    a: 'efsdsdf',
    v: 'sdfdsf' 
};

I think you'll agree that really this object is not useful anywhere I wanted to use an IBase object. 我想你会同意,在我想使用IBase对象的任何地方,这个对象真的 IBase

With this out of the way, you may find the most graceful solution is to create an interface that matches your element definition. 有了这个,您可能会发现最优雅的解决方案是创建一个与您的element定义匹配的接口。

interface IElement {
    base: {
        height?:number;
        width?:number;
    }
}

var element: IElement = {
    base: {
        height: 4
    }
}

The excellent answer from @basarat now needs a little updating; @basarat的优秀答案现在需要一点点更新; using the angle brackets now produces a tslint error: 使用尖括号现在会产生一个tslint错误:

[tslint] Type assertion using the '<>' syntax is forbidden. [tslint]禁止使用“<>”语法键入断言。 Use the 'as' syntax instead. 请改用“as”语法。 (no-angle-bracket-type-assertion) (无尖括号型断言)

The solution is a simple one: 解决方案很简单:

const element = {
    base: {} as IBase
}

This also provides the intellisense (auto-complete) that you'd want as well. 这也提供了您想要的智能感知(自动完成)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM