class ResistorColor {
private colors: string[]
public colorValues = {
black: 0,
brown: 1,
red: 2,
orange: 3,
yellow: 4,
green: 5,
blue: 6,
violet: 7,
grey: 8,
white: 9
}
constructor(colors: string[]) {
if( colors.length > 2)
{
for( key in this.colorValues)
{
if (this.colorValues[key].indexOf(colors[0]) !== -1)
{
return key;
}
}
}
this.colors = colors
}
}
Idea is to find whether the color that has been input by the user is present in the object colorValues
or not.
I referred to this: Find a value in a JavaScript object
I am getting the error of cannot find name key
. I am using a Typescript, online editor.
Please explain to me what am I doing wrong here.
Look at @Owl 's answer, it fixes the other problems in your code too.
In your loop the variable key
is not defined. You'd have to write it like this:
for (const key in this.colorValues) {
...
}
Although I wouldn't use a for-in loop, since objects have their own prototype properties, which you would also receive in a for-in loop. A better solution would be this:
for (const key of Object.keys(this.colorValues) {
...
}
But since you don't need the keys and just use them to retreive the values in the colorValues object, you could also use this:
for (const color of Object.values(this.colorValues) {
...
}
The cannot find name key
error is answered by @MrCodingB
A nicer way to write this:
class ResistorColor {
private colors: string[]
public colorValues = {
black: 0,
brown: 1,
red: 2,
orange: 3,
yellow: 4,
green: 5,
blue: 6,
violet: 7,
grey: 8,
white: 9
}
constructor(colors: string[]) {
const colorValues = Object.keys(this.colorValues);
// colorValues is ["black", "brown", "red", ...]
const isValid = colors.every(c => colorValues.includes(c));
// `every` is used to tests whether all elements in the array pass the test implemented by the provided function,
// in this case, we check whether each value exists in `colorValues`
if (isValid) {
this.colors = colors
} else {
throw new Error("Invalid Color(s)");
}
}
}
const resistorColor = new ResistorColor(["black", "brown"]); // correct
console.log("resistorColor has correct color");
const resistorColor2 = new ResistorColor(["black", "brown", "gold"]); // throws error
console.log("resistorColor2 has correct color");
It's also possible to print out the incorrect colors value by using .filter()
class ResistorColor {
private colors: string[]
public colorValues = {
black: 0,
brown: 1,
red: 2,
orange: 3,
yellow: 4,
green: 5,
blue: 6,
violet: 7,
grey: 8,
white: 9
}
constructor(colors: string[]) {
const colorValues = Object.keys(this.colorValues);
const invalidColors = colors.filter(c => !colorValues.includes(c));
if (invalidColors.length === 0) {
this.colors = colors
} else {
throw new Error(`Invalid Color -> ${invalidColors.join(", ")}`);
}
}
}
const resistorColor = new ResistorColor(["black", "brown"]); // correct
console.log("resistorColor has correct color");
const resistorColor2 = new ResistorColor(["black", "brown", "gold", "foo"]); // throws error "Invalid Color -> gold, foo"
Some of the errors that you are trying to prevent at run-time can be avoided at compile-time with stricter types. You can create a type that only allows specific string literal color names and you can also enforce a minimum length on the colors
array using tuple types .
It looks like this.colorValues
might just be an enum
?
enum COLOR_VALUES {
black = 0,
brown = 1,
red = 2,
orange = 3,
yellow = 4,
green = 5,
blue = 6,
violet = 7,
grey = 8,
white = 9
}
type ColorNames = keyof typeof COLOR_VALUES;
class ResistorColor {
// can have two or more colors
constructor(private colors: [ColorNames, ColorNames, ...ColorNames[]]) {
}
}
Now you can only call the constructor with valid arguments.
const a = new ResistorColor(["black", "blue"]); // ok
const b = new ResistorColor(["black", "blue", "red"]); // ok
const c = new ResistorColor(["black"]); // error: Source has 1 element(s) but target requires 2.
const d = new ResistorColor(["white", "cyan"]); // error: Type '"cyan"' is not assignable to type
If this.colorValues
is an instance variable I would create the initial value outside of the class so that we can use typeof
.
const initialValues = {
black: 0,
brown: 1,
red: 2,
orange: 3,
yellow: 4,
green: 5,
blue: 6,
violet: 7,
grey: 8,
white: 9
}
type ColorNames = keyof typeof initialValues;
class ResistorColor {
public colorValues = initialValues;
// can have two or more colors
constructor(private colors: [ColorNames, ColorNames, ...ColorNames[]]) {
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.