2016-01-15 56 views
2

在TypeScript中将某些属性标记为要求的正确方法是什么?比方说,我们有一定的对象,必须包含ID领域,但它希望还可以有很多其他领域:在TypeScript中设置必要的属性

interface SomeType { 
    id: number; 
} 

let obj: SomeType = { name: "OBJ" };   // GOOD ERROR! We must have `id` 
let obj: SomeType = { id: 123 };    // OK 
let obj: SomeType = { id: 123, name: "OBJ" }; // BAD ERROR! I just want to add a name 

我不知道,你可以使可选属性有一个问号,这样:

interface SomeType { 
    id: number; 
    name?: string; 
    engine?: string; 
    mother?: string; 
} 

但我不希望每次都通过添加和混合无关的东西来修改这个接口。

另一种选择当然是创建一个群的扩大主要各有一个接口,但听起来很多行代码:

interface SomeType { 
    id: number; 
} 

interface FirstType extends SomeType { 
    name: string; 
} 

起初,我试着这样做:

interface SomeType extends any { 
    id: number; 
} 

但是TypeScript找不到名字any。也许有这样的感叹号吗?

interface SomeType { 
    id!: number; 
} 

UPDATE

创建Redux行动,必须有属性type和任意数量的其他附加属性时,我用这类型的接口。实际上有很多操作,所以我不愿意使用any作为一种类型。

+2

*“设置必需的属性”* - 你确定*那是你想要做的吗?对我来说听起来更像是你想定义一个具有一些(必需)属性的类型,但允许任何数量的其他未定义的属性。请显示您真正想要如何使用此类型的用法,以便我们获得您想要执行此操作的目的。 – poke

回答

3

您可以使用,一个indexer

interface SomeType { 
    id: number; 
    [key: string]: any; 
} 

let obj1: SomeType = { name: "OBJ" };   // GOOD ERROR! We must have `id` 
let obj2: SomeType = { id: 123 };    // OK 
let obj3: SomeType = { id: 123, name: "OBJ" }; // OK 

[Playground]

但是,请注意,即使下面的代码(即非字符串属性键)是有效的与上面的索引器:

let obj4: SomeType = { id: 123, 1: "OBJ" }; // also OK 

它混淆了人,但它是就这样。

+0

伟大的解决方法!非常感谢! –

0

请尝试如下。

interface SomeType { 
    id: number; 
    [key: string]: any; 
} 
1

但我不想每次都通过添加和混合不相关的东西来修改这个接口。

不要在同一界面中添加或混合不相关的东西。创建单独的接口,然后在必要时使用交集类型将它们组合。

interface FirstType { 
    id: number; 
} 

interface SecondType { 
    name: string; 
} 

let myIntersectionObj: FirstType & SecondType = { 
    id: 2, 
    name: "some string" 
}; 

这就是在这样的情况下非常有用:

function myFirstFunction(obj: FirstType) { /* does something */ } 
function mySecondFunction(obj: SecondType) { /* does something */ } 

function myFunction(obj: FirstType & SecondType) { 
    myFirstFunction(obj); 
    mySecondFunction(obj); 
} 

myFunction(myIntersectionObj); 

使用交集类型有助于确保一切都在应用程序类型的,这将有助于防止错误。索引类型理想情况下应该只用于键值对象。

+0

谢谢您的贡献,真正学到了关于界面组合的新内容!但仍然需要接受另一个,因为这正是我所要求的。 – mseimys