![](/img/trans.png)
[英]Dynamic copy only some properties between 2 same typed object in Typescript
[英]TypeScript: Dynamically set typed object properties
我是 TypeScript 的新手,我正在尝试将一些自定义组件/插件移植到 TS。
我似乎无法正确设置的一件事是动态设置(键入)object 属性(即,当属性名称是变量时)。
对此的最佳实践解决方案/模式真的会帮助我。
我的代码:
interface Options {
repeat: boolean;
speed: number;
}
class MyPlugIn {
$el:HTMLElement;
options:Options;
constructor ($el:HTMLElement, options:Partial<Options> = {}) {
this.$el = $el;
// Set default options, override with provided ones
this.options = {
repeat: true,
speed: 0.5,
...options
};
// Set options from eponymous data-* attributes
for (const option in this.options) {
if (this.$el.dataset[option] !== undefined) {
let value: any = this.$el.dataset[option];
// Cast numeric strings to numbers
value = isNaN(value) ? value : +value;
// Cast 'true' and 'false' strings to booleans
value = (value === 'true') ? true : ((value === 'false') ? false : value)
// Attempt 1:
// ERROR: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Options'.
this.options[option] = value;
~~~~~~~~~~~~~~~~~~~~
// Attempt 2 (with assertions):
// ERROR (left-hand): Type 'string' is not assignable to type 'never'
// ERROR (right-hand): Type 'option' cannot be used as an index type.
this.options[option as keyof Options] = value as typeof this.options[option];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
}
}
/* ... */
}
/* ... */
}
谢谢!
在你的情况下,他们不是很多选择。 由于 Options 具有不同类型的键,因此您可以执行以下操作
const data = this.$el.dataset[option];
if (data !== undefined) {
if(option === 'repeat') {
const value: boolean = Boolean(data);
this.options.repeat = value;
...
}
...
}
或者使用开关盒。
问题在于从字符串转换为您的类型(数字/ boolean /...)
我不能说这是否是最佳实践,但这种方法对我来说似乎是明智的。 我会通过另一个属性genericOptions
修改Options
接口:
interface Options {
repeat: boolean;
speed: number;
genericOptions: { [key: string]: string };
}
此属性是可以通过字符串索引以返回字符串的任何旧类型。
你的构造函数现在看起来像这样:
constructor ($el:HTMLElement, options:Partial<Options> = {}) {
this.$el = $el;
// Set default options, override with provided ones
this.options = {
repeat: true,
speed: 0.5,
// Just an empty object by default, or you could make the `genericOptions`
// optional, depending on preference.
genericOptions: {},
...options
};
// Set options from eponymous data-* attributes
for (const option in this.options) {
if (this.$el.dataset[option] !== undefined) {
let value: any = this.$el.dataset[option];
// Cast numeric strings to numbers
value = isNaN(value) ? value : +value;
// Cast 'true' and 'false' strings to booleans
value = (value === 'true') ? true : ((value === 'false') ? false : value)
// Set whatever generic options you need to.
this.options.genericOptions[option] = value;
}
}
/* ... */
}
简而言之,只需让 TSC 知道您的Option类型将具有动态属性。
interface Options {
[key: string]: unknown;
repeat: boolean;
speed: number;
}
然后您可以继续动态分配值
this.options[option] = value;
您的问题与此处描述的问题非常相似
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.