Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable 'test' is used before being assigned - Typescript

I am getting error in this implementation of typescript code. I am mapping here one type to another. But vscode shows error that variable 'test' is used before being assigned. can anyone please help?

interface A {
   name: string;
   age: string;
   sex: string;
}

interface B {
   name: any;
   age: string;
   sex: string;
 }

const modifyData = (g : B) :A => {

    let test: A;
    test.name = g.name['ru'];
    test.age = g.age;
    test.sex = g.sex;

   return test as A;
};

const g = [{
  "name": {
      "en": "George",
      "ru": "Gregor"
       },
  "age": "21",
  "sex": "Male"
},
{
  "name": {
      "en": "David",
      "ru": "Diva"
       },,
  "age": "31",
  "sex": "Male"
}];

const data = g.map(modifyData);
console.log(data);
like image 246
dhruv2204 Avatar asked Jun 29 '17 18:06

dhruv2204


3 Answers

To clarify a little, this hinges on the difference between "assigned" and "defined." For example:

let myDate: Date; // I've defined my variable as of `Date` type, but it still has no value.

if (!someVariable) {
   myDate = new Date();
}

console.log(`My date is ${myDate}`) // TS will throw an error, because, if the `if` statement doesn't run, `myDate` is defined, but not assigned (i.e., still has no actual value).
   

Defining simply means giving it an initial value:

let myDate: Date | undefined = undefined; // myDate is now equal to `undefined`, so whatever happens later, TS won't worry that it won't exist.

like image 52
Andrew Avatar answered Nov 02 '22 19:11

Andrew


The error is triggered because typescript sees the variable still as undefined in some scenarios. Adding !before variable tells typescript to remove undefined or null as possibles types for variable:

let test!: A;

Definite assignment assertions doc

Playground: typescript/playground

like image 56
princekin Avatar answered Nov 02 '22 20:11

princekin


It is indeed unassigned. It is defined, but it has no value.

In my humble opinion, the cleanest way would be to return a literal:

const modifyData = (g: B):A => {
    return {
        name: g.name['ru'],
        age: g.age,
        sex: g.sex
    } as A;
};
like image 17
mleko Avatar answered Nov 02 '22 21:11

mleko