I am trying to assign properties to an object to form a known interface called ParsedArguments and this is how it looks like:
import {Rules} from "../Rules/types/Rules";
export interface ParsedArguments {
//other props
//...
rules?: Rules,
}
And now in another function I am trying to form an object that reads values from cli and forms an objects complies to that interface. Something like this:
private parseCliArgs(args: string[]): ParsedArguments {
let res: ParsedArguments = {}
for (const arg of args) {
if (arg.startsWith('--')) {
const {key, value} = this.getArgValues(arg)
if (!res.rules) {
res.rules = {}
}
const rule: keyof Rules = key
if (res.rules[rule]) {
//HERE I GET THE ERROR
//TS2322: Type 'STRING' is not assignable to type 'undefined'.
res.rules[rule] = value
}
}
}
return res
}
Even if I check if the property of Rules exists, it still gives me that error. I couldn't figure out yet and hope you guys help me on this. Here is how Rules look like:
export interface Rules {
someProp1?: boolean,
someProp2?: number,
//...
}
I also tried const rule = key as keyof Rules instead of const rule: keyof Rules = key, doesn't change anything.
I'd appreciate if you guys let me know if you guys need more clarification or I missed any parts. Thanks in advance guys.
You don't have compatible types in Rules and value. In Rules you have optional boolean and number (so they implicitly includes undefined) and in value you always have string.
If you will make all props in Rules as strings then they will be compatible.
See this playground to get a better view of what I mean
OK here is what I come up with. I used built-in Typescript generics which is quite useful in those case. Because in order to get those dynamic results, it is not quite wise to define different types all the time. You will end up cascade of types then. See below:
let rules: Partial<Record<keyof Rules, string>> = {}
for (const arg of args) {
if (arg.startsWith('--')) {
const {key, value} = this.getArgValues(arg)
if (this.isRuleKey(key)) {
rules[key] = value
}
}
}
Now with this solution I don't have to create another version of Rules type. Everything works fine.