0

I started learning typescript, so I'm creating situations to resolve, I'm getting error not sure why, see code above:

interface IObjct {
  name: string,
  city: string,
  age: number,
}


const john = {
  name: "John",
  city: "London",
  age: 24
};

const jerry = {
 name: "Jerry",
 city: "Rome",
 age: 43
};

function filterPerson(arr: Array<IObjct>, term: string, key: string) {
  return arr.filter(function(person) {
    return person[key].match(term);
  });
}

I'm getting error on line : return person[key].match(term);

person[key]

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IObjct'.

No index signature with a parameter of type 'string' was found on type 'IObjct'.ts(7053)

filterPerson([john, jerry], "London", "city");
bernlt
  • 405
  • 2
  • 8
  • 20
  • 7
    See the [FAQ entry](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#general-types): don't use `String` or `Number`; use `string` and `number` instead – jcalz Oct 28 '19 at 14:13
  • 2
    Possible duplicate of [Typescript primitive types: any difference between the types “number” and “Number” (is TSC case-insensitive)?](https://stackoverflow.com/questions/15487220/typescript-primitive-types-any-difference-between-the-types-number-and-numbe) – jcalz Oct 28 '19 at 14:16
  • 1
    @jcalz fully agree with don't use `String` but the deeper issue is that `key` should probbaly be a `keyof T` or a filtered version of that to allow the `person[key]` access – Titian Cernicova-Dragomir Oct 28 '19 at 14:17
  • @TitianCernicova-Dragomir sure; ultimately they will find that `key` should be of type `"name" | "city"` and not `keyof IObjct` and not `string` and not `String`. Not sure how far down the rabbit hole to go here. – jcalz Oct 28 '19 at 14:22
  • @jcalz not sure I understood, when I update String to string, on person[key], I get error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IObjct'. No index signature with a parameter of type 'string' was found on type 'IObjct'.ts(7053). – bernlt Oct 28 '19 at 14:28
  • The short answer is going to be "change the `key` annotation from type `string` to type `"name" | "city"`. The medium answer is that you only want to allow `"name"` and `"city"` as values for `key`, since anything else will lead to a runtime error, which is what the compiler is warning you about. The long answer is too long for comments, and I'm not inclined to write it up as an answer because the question as asked is about `String` and not the subsequent issues you run into when you fix that. Good luck! – jcalz Oct 28 '19 at 14:37

2 Answers2

0

I think, this should solve your problem:

interface IObjct {
    name: string;
    city: string;
    age: number;
}


const john = {
    name: "John",
    city: "London",
    age: 24,
};

const jerry = {
    name: "Jerry",
    city: "Rome",
    age: 43,
};

function filterPerson(arr: IObjct[], term: string, key: string) {
    return arr.filter(function (person) {
        return person[key].match(term);
    });
}
-1

You may do something like below to check for the types:

interface IObjct {
  name: string,
  city: string,
  age: number,
 
}


const john = {
  name: "John",
  city: "London",
  age: 24
};

const jerry = {
 name: "Jerry",
 city: "Rome",
 age: 43
};

function filterPerson(arr: Array<IObjct>, term: string, key: keyof IObjct):Array<IObjct> {
  return arr.filter(function (person: IObjct) {
    const pers = person[key];
    if (typeof pers === "string") {
      return pers.match(term);
    }
    else {
      return false;
   }
  });
}

const results = filterPerson([john, jerry], "London", "city");
console.log(results);
Vishnu
  • 897
  • 6
  • 13