According to TypeScript's documentation on interfaces,
An interface declaration is another way to name an object type.
If that's the case, why do I get an error in the code below? I'm trying to "narrow" down the object
type in the arrow function parameter with an interface.
interface Person {
name: string;
}
type ObjToString = (obj: object) => string;
const personToString: ObjToString = (obj: Person) => obj.name;
// This causes the error ^^^^^^
Error message:
Type '(obj: Person) => string' is not assignable to type 'ObjToString'.
Types of parameters 'obj' and 'obj' are incompatible.
Property 'name' is missing in type '{}' but required in type 'Person'.
However, I can assign a variable of type Person
to a variable of type object
:
let obj: object;
const person: Person = { name: "Tom" };
obj = person; // OK
Is there any reason why the error occurs at the arrow function parameter only? How can I fix this problem?
CodePudding user response:
You are trying to assign a function that requires a Person
object to a function that is typed to accept any object. IOW, you could then call personToString
as follows:
personToString({ whatever: "hello" });
Obviously this cannot work, which is why the compiler complains.
CodePudding user response:
object
type itself does not have any properties. And that is the issue you are getting. object
is a very restrictive type.
If you want to use any type of object, just use any
.
type ObjToString = (obj: any) => string;
interface Person {
name: string;
}
const personToString: ObjToString = (obj: Person) => obj.name;
Also, Typescript's behaviour is such that does not complain when you pass extra properties to a type which was expecting lesser properties. But it would definitely complain is the minimum required properties are not present.
Look at this example :
interface Student {
school : string;
name : string;
}
interface Human {
name : string;
}
let x : Student = {
name: 'Test',
school: 'Test'
};
let y : Human = {
name : 'test'
};
// x = y;
y = x;
The statement x=y
will give an error but y=x
will not do it. You can assign Student
to Human
, but not Human
to Student
.
That is what is happening in your code, TS is complaining because Person
requires name
and it is missing in object
({}). object
requires nothing and name
is just an extra property being passed to the variable obj
.
CodePudding user response:
The TypeScript object
type represents all values that are not in primitive types.
The main issue here is trying to access a property called 'name' from an 'object' which is translated to {} and does not have 'name' property.
you could help Typescript understand what you are trying to do by using generics:
interface Person {
name: string;
}
type ObjToString<T> = (obj: T) => string;
const personToString: ObjToString<Person> = (obj: Person) => obj.name;
const aPerson: Person = {name: 'test_name'};
const aPersonName = personToString(aPerson);
console.log(aPersonName)