joh*_*thy 18 javascript typescript
我正在尝试使用以下模式:
enum Option {
ONE = 'one',
TWO = 'two',
THREE = 'three'
}
interface OptionRequirement {
someBool: boolean;
someString: string;
}
interface OptionRequirements {
[key: Option]: OptionRequirement;
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很简单,但是出现以下错误:
索引签名参数类型不能为联合类型。考虑改用映射对象类型。
我究竟做错了什么?
Ame*_*icA 122
就我而言:
\nexport type PossibleKeysType =\n | \'userAgreement\'\n | \'privacy\'\n | \'people\';\n\ninterface ProviderProps {\n children: React.ReactNode;\n items: {\n // \xe2\x86\x99 this colon was issue\n [key: PossibleKeysType]: Array<SectionItemsType>;\n };\n}\nRun Code Online (Sandbox Code Playgroud)\nin我通过使用运算符而不是使用来修复它:
~~~\n\ninterface ProviderProps {\n children: React.ReactNode;\n items: {\n // \xe2\x86\x99 use "in" operator\n [key in PossibleKeysType]: Array<SectionItemsType>;\n };\n}\nRun Code Online (Sandbox Code Playgroud)\n
Nac*_*mos 32
您可以使用TS“ in”运算符,并执行以下操作:
enum Options {
ONE = 'one',
TWO = 'two',
THREE = 'three',
}
interface OptionRequirement {
someBool: boolean;
someString: string;
}
interface OptionRequirements {
[key in Options]: OptionRequirement; // Note that "key in".
}
Run Code Online (Sandbox Code Playgroud)
Kur*_*gor 21
我有一些类似的问题,但我的情况是接口中的另一个字段属性,所以我的解决方案作为一个示例,带有可选字段属性和键枚举:
export enum ACTION_INSTANCE_KEY {
cat = 'cat',
dog = 'dog',
cow = 'cow',
book = 'book'
}
type ActionInstances = {
[key in ACTION_INSTANCE_KEY]?: number; // cat id/dog id/cow id/ etc // <== optional
};
export interface EventAnalyticsAction extends ActionInstances { // <== need to be extended
marker: EVENT_ANALYTIC_ACTION_TYPE; // <== if you wanna add another field to interface
}
Run Code Online (Sandbox Code Playgroud)
uni*_*nal 17
最简单的解决方案是使用 Record
type OptionRequirements = Record<Options, OptionRequirement>
Run Code Online (Sandbox Code Playgroud)
您也可以自己实现为:
type OptionRequirements = {
[key in Options]: OptionRequirement;
}
Run Code Online (Sandbox Code Playgroud)
此构造仅可用于type,但不可用interface。
定义中的问题是接口的键应该是类型Options,其中Options是枚举,而不是字符串,数字或符号。
在key in Options“为这是在联合类型选择那些特定的键”的意思。
type别名比别名更灵活和强大interface。
如果你的类型并不需要在课堂上使用,选择type了interface。
Ste*_*fan 15
使用映射对象类型而不是使用接口
enum Option {
ONE = 'one',
TWO = 'two',
THREE = 'three'
}
type OptionKeys = keyof typeof Option;
interface OptionRequirement {
someBool: boolean;
someString: string;
}
type OptionRequirements = { // note type, not interface
[key in OptionKeys]: OptionRequirement; // key in
}
Run Code Online (Sandbox Code Playgroud)
小智 11
在我的情况下,我需要属性是可选的,所以我创建了这个通用类型。
type PartialRecord<K extends string | number | symbol, T> = { [P in K]?: T; };
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
type MyTypes = 'TYPE_A' | 'TYPE_B' | 'TYPE_C';
interface IContent {
name: string;
age: number;
}
interface IExample {
type: string;
partials: PartialRecord<MyTypes, IContent>;
}
Run Code Online (Sandbox Code Playgroud)
例子
const example : IExample = {
type: 'some-type',
partials: {
TYPE_A : {
name: 'name',
age: 30
},
TYPE_C : {
name: 'another name',
age: 50
}
}
}
Run Code Online (Sandbox Code Playgroud)
已编辑
TL;DR:使用Record<type1,type2>或映射对象,例如:
type YourMapper = {
[key in YourEnum]: SomeType
}
Run Code Online (Sandbox Code Playgroud)
我遇到了类似的问题,问题是键允许的类型是字符串、数字、符号或模板文字类型。
因此,正如 Typescript 所建议的,我们可以使用映射的对象类型:
type Mapper = {
[key: string]: string;
}
Run Code Online (Sandbox Code Playgroud)
请注意,在映射对象中,我们只允许使用字符串、数字或符号作为键,因此如果我们想使用特定字符串(即 emum 或 union 类型),我们应该in在索引签名中使用关键字。这用于引用枚举或联合中的特定属性。
type EnumMapper = {
[key in SomeEnum]: AnotherType;
};
Run Code Online (Sandbox Code Playgroud)
在现实生活中的例子中,假设我们想要得到这个结果,一个它的键和值都是指定类型的对象:
const notificationMapper: TNotificationMapper = {
pending: {
status: EStatuses.PENDING,
title: `${ENotificationTitels.SENDING}...`,
message: 'loading message...',
},
success: {
status: EStatuses.SUCCESS,
title: ENotificationTitels.SUCCESS,
message: 'success message...',
},
error: {
status: EStatuses.ERROR,
title: ENotificationTitels.ERROR,
message: 'error message...'
},
};
Run Code Online (Sandbox Code Playgroud)
为了使用 Typescript 实现此目的,我们应该创建不同的类型,然后在 Record<> 中或使用映射的对象类型来实现它们:
export enum EStatuses {
PENDING = 'pending',
SUCCESS = 'success',
ERROR = 'error',
}
interface INotificationStatus {
status: string;
title: string;
message: string;
}
//option one, Record:
type TNotificationMapper = Record<EStatuses, INotificationStatus>
//option two, mapped object:
type TNotificationMapper = {
[key in EStatuses]:INotificationStatus;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我使用枚举,但这种方法适用于枚举和联合类型。
*注意-使用括号而不是方括号的类似语法(即 this(...)而不是 this [...],可能不会显示任何错误,但它表示完全不同的东西,一个函数接口,所以这样:
interface Foo {
(arg:string):string;
}
Run Code Online (Sandbox Code Playgroud)
实际上是描述一个函数签名,例如:
const foo = (arg:string) => string;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5373 次 |
| 最近记录: |