我正在使用的一个lib(Aphrodite)有这种类型的定义:
interface StyleDeclaration {
[key: string]: CSSProperties;
}
我想创建一个子类型,其中key
必须是指定列表的子集,但子类型可以用作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 :(得分: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
答案 1 :(得分:0)
这不是一个答案(对我自己的问题),但如果我可以更改StyleDeclaration
,我会将其更改为
type StyleDeclaration<K extends string = string> = {
[key in K]: CSSProperties;
}
使一切顺利。 = string
是通用的默认值,是TS 2.3中的新功能。