如何使用具有静态和动态类型属性的类型
How to use a type with static and dynamic typed properties
我正在尝试使用一种类型,它具有一种类型的所有属性,但也允许添加另一种类型的动态属性(类似于此 )。
类型定义如下:
type Foo = string | string[]
type Bar = { n: number, str?: string }
// A dictionary which only allows Foo values
type FooDict = { [key: string]: Foo | undefined }
// Has all static properties of Bar plus some dynamic Foo properties
type FooBar = FooDict & Bar
我希望像这样使用它们:
const bar: Bar = { n: 1 }
const fooBar: FooBar = bar
const n: number = fooBar.n
const str: string | undefined = fooBar.str
const foo: Foo | undefined = fooBar['someRandomKey']
问题是第二行给出编译错误:"Type 'Bar' is not assignable to type 'FooBar'。Type 'Bar' is not assignable to type 'FooDict'.属性 'n' 与索引签名不兼容。类型 'number' 不可分配给类型 'Foo | undefined'。TS2322".
我看不出它无法工作的任何原因。
Bar
和FooDict
的键都是字符串,所以没有不匹配。
- 如果使用
Bar
的key,我们可以使用Bar对应的静态属性。
- 否则,我们可以使用
FooDict
中的类型,它是 Foo
(当 属性 存在时)或 undefined
(当使用不带键的键时)值)。
如链接问题中所述,如果将动态属性键入 any
,则此方法有效。但由于我只需要将 Foo 实例设置为动态属性,我想用类型系统强制执行它。这可能吗?
简短的回答是 FooBar
和 Bar
不兼容,因为 FooBar
承诺基于字符串的索引签名而 Bar
不兼容。 (基本上这就是错误信息所说的)
const fooBar: FooBar = {...}
const bar: Bar = fooBar;
// this will work since foobar has a string index signature
fooBar['someRandomKey'] // undefined | Foo
// this will give a compilation error since there is no string based index signature
bar['someRandomKey'] // NOTE: it will work at runtime though (which is why it is so confusing)
如果您想将 Bar
分配给 Foobar
,您必须提供相应的签名,该签名基本上等于您的 FooBar
类型。
将 FooBar
分配给 Bar
应该总是可行的
我正在尝试使用一种类型,它具有一种类型的所有属性,但也允许添加另一种类型的动态属性(类似于此
类型定义如下:
type Foo = string | string[]
type Bar = { n: number, str?: string }
// A dictionary which only allows Foo values
type FooDict = { [key: string]: Foo | undefined }
// Has all static properties of Bar plus some dynamic Foo properties
type FooBar = FooDict & Bar
我希望像这样使用它们:
const bar: Bar = { n: 1 }
const fooBar: FooBar = bar
const n: number = fooBar.n
const str: string | undefined = fooBar.str
const foo: Foo | undefined = fooBar['someRandomKey']
问题是第二行给出编译错误:"Type 'Bar' is not assignable to type 'FooBar'。Type 'Bar' is not assignable to type 'FooDict'.属性 'n' 与索引签名不兼容。类型 'number' 不可分配给类型 'Foo | undefined'。TS2322".
我看不出它无法工作的任何原因。
Bar
和FooDict
的键都是字符串,所以没有不匹配。- 如果使用
Bar
的key,我们可以使用Bar对应的静态属性。 - 否则,我们可以使用
FooDict
中的类型,它是Foo
(当 属性 存在时)或undefined
(当使用不带键的键时)值)。
如链接问题中所述,如果将动态属性键入 any
,则此方法有效。但由于我只需要将 Foo 实例设置为动态属性,我想用类型系统强制执行它。这可能吗?
简短的回答是 FooBar
和 Bar
不兼容,因为 FooBar
承诺基于字符串的索引签名而 Bar
不兼容。 (基本上这就是错误信息所说的)
const fooBar: FooBar = {...}
const bar: Bar = fooBar;
// this will work since foobar has a string index signature
fooBar['someRandomKey'] // undefined | Foo
// this will give a compilation error since there is no string based index signature
bar['someRandomKey'] // NOTE: it will work at runtime though (which is why it is so confusing)
如果您想将 Bar
分配给 Foobar
,您必须提供相应的签名,该签名基本上等于您的 FooBar
类型。
将 FooBar
分配给 Bar
应该总是可行的