admin管理员组文章数量:1405170
I have a data class
export interface MusicDto {
title?: string;
artist?: string;
//...
}
I would like to fill it with data from key/value tokens
tokens.forEach(token => {
const [key, value] = token.split(':');
if (key && value) {
const propertyName = key.trim().toLowerCase() as keyof MusicDto;
const propertyValue = value.replace(';', '').trim();
let targetProperty = musicData[propertyName];
if (targetProperty) {
switch (typeof targetProperty) {
case 'string': targetProperty = propertyValue;
break;
case 'number': targetProperty = parseFloat(propertyValue);
break;
default:
}
} else {
console.log(`Unknown property ${propertyName}`);
}
}
});
But all properties are going to "Unknown property"
Here a playground which reproduces it
I have a data class
export interface MusicDto {
title?: string;
artist?: string;
//...
}
I would like to fill it with data from key/value tokens
tokens.forEach(token => {
const [key, value] = token.split(':');
if (key && value) {
const propertyName = key.trim().toLowerCase() as keyof MusicDto;
const propertyValue = value.replace(';', '').trim();
let targetProperty = musicData[propertyName];
if (targetProperty) {
switch (typeof targetProperty) {
case 'string': targetProperty = propertyValue;
break;
case 'number': targetProperty = parseFloat(propertyValue);
break;
default:
}
} else {
console.log(`Unknown property ${propertyName}`);
}
}
});
But all properties are going to "Unknown property"
Here a playground which reproduces it
Share Improve this question edited Mar 8 at 23:31 Jason Aller 3,65228 gold badges41 silver badges39 bronze badges asked Mar 8 at 19:56 FoxhuntFoxhunt 9222 gold badges13 silver badges31 bronze badges 3 |1 Answer
Reset to default 1You cannot fill an object this way by assigning to it's extracted value. You need to refer to the property directly. Also your initial class instance is totally empty so you can't get any runtime types from it.
A solution with fixes for these problems:
// Here the data
const anExampleVariable = `
#TITLE:ROOM;
#ARTIST:Blanc Bunny Bandit;
#BANNER:ROOM.png;
#BACKGROUND:ROOM-bg.png;
#CDTITLE:./CDTitles/DDR A20 PLUS.png;
#MUSIC:ROOM.ogg;
#SAMPLESTART:57.5;
#SAMPLELENGTH:15;
#BPMS:0=145;
`
const tokens = anExampleVariable.split('#').map(token => token.trim()).filter(token => token.length > 0);
// Here my target DTO
class MusicDto {
title?: string = '';
artist?: string = '';
banner?: string = '';
background?: string = '';
cdTitle?: string = '';
music?: string = '';
sampleStart?: number = 0;
sampleLength?: number = 0;
bpms?: string = '';
notes: number[][][] = [];
}
const musicData: MusicDto = new MusicDto()
const newData = tokens.reduce((r, item) => {
const [key, value] = item.split(':');
r[key.toLowerCase()] = value.slice(0,-1);
return r;
}, {} as Record<string, string>);
const foundKeys: string[] = [];
const keys = <T extends object>(obj: T) => Object.keys(obj) as (keyof T)[];
keys(musicData).forEach(name => {
const lower = name.toLowerCase();
if(lower in newData){
foundKeys.push(lower);
const value = newData[lower];
if(typeof musicData[name] === 'string'){
(musicData as any)[name] = value; // you could use a custom type guard
}else if(typeof musicData[name] === 'number'){
(musicData as any)[name] = parseFloat(value); // you could use a custom type guard
}
}
});
const notFoundKeys = Object.keys(newData).filter(k => !foundKeys.includes(k));
console.log('not found:', notFoundKeys);
console.log(musicData)
本文标签: typescriptFill class properties with keyvalue dataStack Overflow
版权声明:本文标题:typescript - Fill class properties with keyvalue data - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744886444a2630516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
musicData
and what is the significance ofmusicData[propertyName]
? I don't get why you've called the result of thattargetProperty
when it will be the value of the property. And even then, it will only be the value if that is already set. But even assuming you get over these hurdles assigning totargetProperty
is not going to do anything at all. – VLAZ Commented Mar 8 at 20:56targetProperty
doesnt changemusicData
, please reproduce your problem on typescriptlang./play – Alexander Nenashev Commented Mar 8 at 22:27