Lets say I want to define a function that accepts one argument that must be an object which keys are strings and values can be for example number | string
like it done in the bottom example.
const fn = (param: Record<string, string | number>) => {
console.log(param);
};
const p = {
id: 1,
name: 'John'
};
fn(p);
the above example will work just fine, but when I want to give an explicit type to variable p
with using typescript's type
as in the bottom example, everything working just fine again.
const fn = (param: Record<string, string | number>) => {
console.log(param);
};
type User = {
id: number;
name: string;
}
const p: User = {
id: 1,
name: 'John'
};
fn(p);
But when defining type with the typescript interface
as in the example below I'm getting an error saying
TS2345: Argument of type 'User' is not assignable to parameter of type 'Record<string, string | number>'
.
Index signature for type 'string' is missing in type 'User'.
const fn = (param: Record<string, string | number>) => {
console.log(param);
};
interface User {
id: number;
name: string;
}
const p: User = {
id: 1,
name: 'John'
};
fn(p);
So what is the reason for such a behavior?
How can I define type for function argument to be an object which keys should be string
and values can be union type for example string | number
and will work with both type
s and interface
s?
CodePudding user response:
REVISED:
You can destructure the object p
as such when calling the function:
fn({ ...p });
This takes all of the properties of p
and puts them on a new object.
It is also possible to create a new object for the purposes of passing to the function:
const params = {
...p,
};
fn(params);
CodePudding user response:
This should be due to the fact that interfaces are "open" while type aliases are closed, meaning they can not be extended after their initial declaration, unlike interfaces, that can be declared again - which means you could add properties to the interface, that are not assignable to Record<string, string | number>
. This also relates to declaration merging
See this playground for more details