2017-05-06 56 views
0

我使用一個lib(阿芙羅狄蒂)具有這種類型的定義:可以改進Typescript中的索引簽名嗎?

interface StyleDeclaration { 
    [key: string]: CSSProperties; 
} 

我想創建一個亞型,其中key s必須是一個指定列表的一個子集,但亞型可以作爲一個StyleDeclaration

我最好的嘗試是:

type CssTransStyleName = 
    'defaultStyle' | 'activeStyle' | 'etcetera' 

type CssTransStyleDeclaration = {[K in CssTransStyleName]?: CSSProperties} 

這種運作良好,在一定程度上 - 在我嘗試使用實例作爲StyleDeclaration點。例如,給定:

const cssDeclaration: CssTransStyleDeclaration = { 
    style: { 
     transformOrigin: 'top left', 
    }, 
} 
const ss: StyleDeclaration = cssDeclaration 

編譯器抱怨:

Type 'CssTransStyleDeclaration' is not assignable 
to parameter of type 'StyleDeclaration'. 
    Property 'defaultStyle' is incompatible with index signature. 
    Type 'CSSProperties | undefined' is not assignable to type 'CSSProperties'. 
     Type 'undefined' is not assignable to type 'CSSProperties'. 

顯然,編譯器解釋

{[K in CssTransStyleName]?: CSSProperties}

爲意指「在CssTransStyleName每個屬性具有類型的值CSSProperties | undefined,而我試圖說一些屬性會存在,有些則不存在。

鑄造as StyleDeclaration工程,但我不想使用管道膠帶。


我也試過

type CssTransStyleDeclaration = {[K in CssTransStyleName]?: CSSProperties} & StyleDeclaration

但是這有效地使得它一樣只是一個StyleDeclaration;該屬性不限於CssTransStyleName中的屬性。

+0

你能發佈產生錯誤的代碼嗎? –

+0

@shambalambala謝謝,更新 - 見上面 –

回答

1

你可以嘗試以下方法:

interface CssTransStyle { 
    defaultStyle: any; 
    activeStyle: any; 
    etcetera: any; 
} 

type StyleDeclarationOf<T> = { 
    [P in keyof T]: CSSProperties; 
}; 

type CssTransStyleDeclaration = StyleDeclarationOf<CssTransStyle> & StyleDeclaration; 

下面是一個例子,這將有助於你理解它:

interface CSSProperties { 
    someprop: string; 
} 

interface StyleDeclaration { 
    [key: string]: CSSProperties; 
} 

// This functions only accepts StyleDeclaration 
function test(a: StyleDeclaration) { 

} 

var a: StyleDeclaration = { 
    somekey: { 
     someprop: "somevalue" 
    } 
}; 

test(a); // Works fine because a is StyleDeclaration 

interface CssTransStyle { 
    defaultStyle: any; 
    activeStyle: any; 
    etcetera: any; 
} 

type StyleDeclarationOf<T> = { 
    [P in keyof T]: CSSProperties; 
}; 

type CssTransStyleDeclaration = StyleDeclarationOf<CssTransStyle> & StyleDeclaration; 

// Works because b is CssTransStyleDeclaration and StyleDeclaration 
var b: CssTransStyleDeclaration = { 
    defaultStyle: { 
     someprop: "somevalue" 
    }, 
    activeStyle: { 
     someprop: "somevalue" 
    }, 
    etcetera: { 
     someprop: "somevalue" 
    } 
}; 

test(b); // Works fine because is CssTransStyleDeclaration and StyleDeclaration 

// ERROR c is StyleDeclaration but not CssTransStyleDeclaration 
var c: CssTransStyleDeclaration = { 
    somekey: { 
     someprop: "somevalue" 
    } 
}; 

test(c); // Works fine becase c is StyleDeclaration 
+0

謝謝,但我試圖創建一個實例可以包含其屬性的任何子集的類型。 AFAICT,這個解決方案需要爲每個使用的子集創建一個明確的界面。例如,如果你從'var b ...'中移除'activeStyle',編譯器會錯過它並抱怨。 –

0

這不正是一個答案(我自己的問題),但如果我可以改變StyleDeclaration,我將其更改爲

type StyleDeclaration<K extends string = string> = { 
     [key in K]: CSSProperties; 
    } 

使一切工作。 = string是TS 2.3中的一個新功能的默認值。

相關問題