TypeScript just adds a static type system to JavaScript. In JavaScript, your greet() function takes a parameter named obj and then completely ignores it; instead you're using this, whose value is unlikely to be anything useful to you. So you need to use obj instead of this, as the other answers correctly point out.
It was also pointed out that you don't seem to need generics here. You can just make obj of the concrete type {name: string, age: number} and it will work:
function greet(obj: { name: string, age: number }) {
console.log(`Hello, my name is ${obj.name}, I am ${obj.age} years old.`);
}
And greet() will work with p1:
greet(p1); // okay
but complain if you call it with something that is not assignable to the required type:
greet({ name: "the ageless one" }) // error, age is missing
and also if you pass in an object literal with excess properties, due to excess property checking:
greet({ name: "one-eyed jack", age: 45, eyes: 1 }) // excess property warning,
// eyes not expected
If you really want to use generics for this function, you should probably use a generic constraint on your type parameter T, so that the compiler knows that it will have a string-valued name and a numeric-valued age property:
function greet<T extends { name: string, age: number }>(obj: T) {
console.log(`Hello, my name is ${obj.name}, I am ${obj.age} years old.`);
}
So T is still not known exactly inside the implementation of greet(), but we know it has to be some subtype of {name: string, age: number}, and so now there's no compiler error when we read the name and age properties of obj.
Calling greet(p1) works because p1 meets the constraint:
greet(p1); // okay
And, as before, if you pass in something that doesn't meet the constraint you get an error:
greet({ name: "the ageless one" }) // error, age is missing
Finally, if you pass in something more specific than the constraint such as an extra property, there will be no error, and T will be inferred as the more specific type:
greet({ name: "one-eyed jack", age: 45, eyes: 1 }) // okay,
// T is inferred as {name: string, age: number, eyes: number}
Okay, hope that helps; good luck!
Playground link to code
obj.name, obj.ageinstead ofthis. Otherwise you have to bind function to objectgreet.bind(p1)T, it doesn't know aboutnameandage.objinstead ofthis, I get following compiler errors 1) Property 'name' does not exist on type 'T' 2) Property 'age' does not exist on type 'T'. But get expected output (when TS converts code into JS) When I removeobjand usethisinstead, I DON'T get any compilation error.objis generic, the functiongreetdoesn't know it has the propertynameandage. That's why you get compilation errors when you usethis.nameandthis.age(even if it will run correctly)