任意类型定义给出:“boolean"类型的属性“x"不可分配给字符串索引类型“string" [英] arbitrary type definition gives: Property 'x' of type 'boolean' is not assignable to string index type 'string'
问题描述
似乎这个 是相关的,但我不明白.
这是我想要的示例:
myObj
应该接受以下设置:
myObj = {'key1': 'val1', 'key2': 'val2', 'key3': 'val3'};myObj = {'key1': 'val1', 'key2': {'key2': 'val2', 'btnWrap': true}, 'key3': 'val3'};
所以我想出了以下类型定义:
let myObj: {[key: string]: string |{[key: string]: string, btnWrap: boolean}}
<块引用>
'boolean' 类型的属性 'btnWrap' 不能分配给字符串索引类型 'string'.ts(2411)
(我不明白上面的错误信息.)
请注意:
- key1、2、3 代表任意键名.
- 在
'key2': {'key2': 'val2', 'btnWrap': true}
请注意它应该是相同的任意键名.(例如,key2)
很高兴得到一些指导.
<小时>@埃弗特:
让我的对象:{[键:字符串]:字符串|布尔值,btnWrap:布尔值}myObj = {'arr0': 'val0', 'arr1': {'arr1': 'val1', 'btnWrap': false}};
<块引用>
输入'{'arr1':字符串;'btnWrap':布尔值;}' 不能分配给类型 'string |布尔'.输入'{'arr1':字符串;'btnWrap':布尔值;}' 不可分配给类型 'true'.ts(2322)
错误信息是因为 btnWrap
类型 boolean
与 字符串索引 类型 string
.类型 {[key: string]: string, btnWrap: boolean}}
试图说明每个属性都有一个字符串值 and 表示 btnWrap
有一个布尔值.它们不可能都为真,因此编译器会警告您.
没有一个具体的类型 MyObj
代表您所描述的约束.但是您可以创建一个 generic 类型,它采用键字面量 K
的并集并产生一个类型 MyObj
:
type MyObj={ [P in K]: 字符串 |(Record<P, string> & { btnWrap: boolean }) };
类型 代码>.后一种类型本身就是一个映射类型(在标准库中定义) 键 同样,要描述 现在让我们试试: 那些工作得很好.现在让我们看看如果您违反约束会出现什么问题: 那些错误可能正是您想要看到的,对吗? 好的,希望有帮助.这是一个 Playground 链接到上述代码.祝你好运! it seems THIS is related, yet I dont understand. here is an example of what I want: So I came up with the following type definition:
Property 'btnWrap' of type 'boolean' is not assignable to string index type 'string'.ts(2411) (I dont understand the above error message.) Please note: Im happy for some guidance. @Evert:
Type '{ 'arr1': string; 'btnWrap': boolean; }' is not assignable to type 'string | boolean'.
Type '{ 'arr1': string; 'btnWrap': boolean; }' is not assignable to type 'true'.ts(2322)
The error message is because the There isn't a single concrete type The type Again, to describe the type of Now let's try it: Those work just fine. Now let's see what goes wrong if you violate your constraint: Those errors are probably what you want to see, right? Okay, hope that helps. Here's a Playground link to the above code. Good luck! 这篇关于任意类型定义给出:“boolean"类型的属性“x"不可分配给字符串索引类型“string"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!MyObj
是一个 映射类型,其中键为 P
的每个属性要么具有值类型 string
,要么具有 intersection 的 {btnWrap: boolean}
与 Record
P
和属性string
.所以 MyObject<K>
的每个属性必须看起来像 someKey: string
或 someKey: {btnWrap: boolean, someKey: string}
.myObj
的类型,而不是像 let myObj: MyObj = ...
这样简单的东西,你必须像 letmyObj: MyObj<"key1"|"key2"|"key3">= ...
在其中指定通用参数.为了避免您必须自己执行此操作,您可以使用通用辅助函数来帮助 推断给定一个对象的K
的类型,像这样:const asMyObj =
let myObj1 = asMyObj({ key1: 'val1', key2: 'val2', key3: 'val3' });让 myObj2 = asMyObj({ key1: 'val1', key2: { key2: 'val2', btnWrap: true }, key3: 'val3' });
let badMyObj1 = asMyObj({ key1: 1 });//错误,数字不好让 badMyObj2 = asMyObj({ key1: "val1", key2: { key2: "val2" } });//错误,缺少 btnWrap让 badMyObj3 = asMyObj({ key1: "val1", key2: { btnWrap: true } });//错误,缺少 key2 里面的值让 badMyObj4 = asMyObj({ key1: "val1", key2: { key3: "val3", btnWrap: true } });//错误,key3 不是预期的内部值
myObj
should accept the following settings:myObj = {'key1': 'val1', 'key2': 'val2', 'key3': 'val3'};
myObj = {'key1': 'val1', 'key2': {'key2': 'val2', 'btnWrap': true}, 'key3': 'val3'};
let myObj: {[key: string]: string | {[key: string]: string, btnWrap: boolean}}
'key2': {'key2': 'val2', 'btnWrap': true}
please note it should be the SAME arbitrary key-name. (key2 for eg)
let myObj: {
[key: string]: string | boolean,
btnWrap: boolean
}
myObj = {'arr0': 'val0', 'arr1': {'arr1': 'val1', 'btnWrap': false}};
btnWrap
type boolean
doesn't match the string index type string
. The type {[key: string]: string, btnWrap: boolean}}
is trying to say that every property has a string value and that btnWrap
has a boolean value. They can't both be true, so the compiler warns you.
MyObj
that represents the constraint as you described it. But you can create a generic type which takes the union of key literals K
and produces a type MyObj<K>
:type MyObj<K extends keyof any> =
{ [P in K]: string | (Record<P, string> & { btnWrap: boolean }) };
MyObj<K>
is a mapped type where each property with key P
either has value type string
, or the intersection of {btnWrap: boolean}
with Record<P, string>
. The latter type is itself a mapped type (defined in the standard library) with keys P
and properties string
. So each property of MyObject<K>
must either look like someKey: string
or someKey: {btnWrap: boolean, someKey: string}
.myObj
, instead of something simple like let myObj: MyObj = ...
, you have to do something like let myObj: MyObj<"key1"|"key2"|"key3"> = ...
where you specify the generic parameters. To prevent you from having to do this yourself, you can use a generic helper function to help infer the type of K
given an object, like this:const asMyObj = <T extends MyObj<keyof T>>(myObj: T) => myObj;
let myObj1 = asMyObj({ key1: 'val1', key2: 'val2', key3: 'val3' });
let myObj2 = asMyObj({ key1: 'val1', key2: { key2: 'val2', btnWrap: true }, key3: 'val3' });
let badMyObj1 = asMyObj({ key1: 1 });
// error, number is bad
let badMyObj2 = asMyObj({ key1: "val1", key2: { key2: "val2" } });
// error, missing btnWrap
let badMyObj3 = asMyObj({ key1: "val1", key2: { btnWrap: true } });
// error, missing key2 inside value
let badMyObj4 = asMyObj({ key1: "val1", key2: { key3: "val3", btnWrap: true } });
// error, key3 not expected inside value