2017-05-19 43 views
1

我有一个非常复杂的对象,我想要扩展和重写一个特定的属性的多个属性。如何扩展接口并覆盖属性的类型?

interface ComplicatedObject { 
    propertyOne: string, 
    propertyTwo: null 
} 

interface MoreComplicatedObject extends ComplicatedObject { 
    propertyTwo: string 
} 

本质上,对象与ComplicatedObject类型通过向propertyTwo分配一个字符串值被转换为MoreComplicatedType。我想避免在propertyTwo上使用联合类型,因为所有使用propertyTwo的调用都假定它是一个字符串,而不是空值,所以我宁愿不必在每次访问propertyTwo时都包含类型检查。

如何扩展接口并覆盖现有属性的类型?

+0

这样做会违反Liskov替换原则。你可以使'ComplicatedObject'成为一个通用的接口,并且使泛型的'propertyTwo'成为可能?这样你根本不需要'MoreComplicatedObject',并且不违反LSP。 TypeScript 2.3支持默认的类型参数,因此您不必始终提供参数。 – Amy

+0

你可以做的另一件事是使用'Pick'类型来挑选你想保持的属性,然后添加你想要的任何类型的新属性。像''MoreComplicatedObject'扩展Pick {propertyTwo:string; }' – Aaron

回答

1

只有扩展接口中的类型与该属性的原始类型兼容时,才可以在扩展接口时覆盖属性类型。通常的情况是,当你用更限制的类型覆盖它时。

这意味着你必须具有远见,并声明原始属性的类型与所有可能的扩展名兼容。你的情况,你可以在ComplicatedObject使用union类型:

interface ComplicatedObject { 
    propertyOne: string, 
    propertyTwo: null | string 
} 

interface MoreComplicatedObject extends ComplicatedObject { 
    propertyTwo: string 
} 

也可以使CompicatedObject通用在this answer描述。