I have the following class definition:
class Department
{
name: string;
id: string;
get prefix(): string
{
return !isNaN(parseFloat(this.id)) ? "n" : "i" ;
}
}
Elsewhere in my code, I try to use it like this:
getDepartmentList(): Department[] {
return [
{
"name": "Dept 1",
"id": "1000"
}
];
}
However, I get the following error:
Type '{ "name": string; "id": string; }' is not assignable to type 'Department'. Property 'prefix' is missing in type '{ "name": string; "id": string; }'.
I am sure the real problem is my lack of understanding of Typescript, but can someone explain why the compiler sees the getter function as a property and expects me to set a value on it?
Creating Read-Only Properties in TypeScript To create a read-only property, we prefix the keyword readonly before the property name. In the example below the price property is marked as readonly . We can assign a value to the price property when we initialize the object. However, we cannot change its value afterward.
TypeScript includes the readonly keyword that makes a property as read-only in the class, type or interface. Prefix readonly is used to make a property as read-only. Read-only members can be accessed outside the class, but their value cannot be changed.
You can use mapping modifiers to change a readonly property to mutable in TypeScript, e.g. -readonly [Key in keyof Type]: Type[Key] . You can remove the readonly modifier by prefixing the readonly keyword with a minus - .
Typescript can't restrict extra properties Unfortunately this isn't currently possible in Typescript, and somewhat contradicts the shape nature of TS type checking.
Your class Department is creating a type Department. You are defining that to contain name
, id
and prefix
. The objects you return in getDepartmentList
does not contain the prefix
, so they are not structurally compatible with the type Department. Hence you get an error.
I guess that you assume that the prefix
-property will be available on anything do declare to be of the type Department. This is not the case, there is no kind of dynamic class assignments like that in typescript. You have to make sure yourself that objects that you say is certain type, actually fulfill that type.
You could do it something like this:
class Department
{
constructor(public name:string, public id:string){ }
get prefix(): string
{
return !isNaN(parseFloat(this.id)) ? "n" : "i" ;
}
}
function getDepartmentList(): Department[]
{
return [new Department("Dept 1", "1000")];
}
Here you are instantiating new objects from the Department class, hence those objects will all have the prefix property.
The use of the access modifier in the constructor signature is telling typescript to create a property of that parameter, instead of only being treated as an argument.
It's equivalent to:
class Department
{
name: string;
id:string;
constructor(name:string, id:string){
this.name = name;
this.id = id;
}
get prefix(): string
{
return !isNaN(parseFloat(this.id)) ? "n" : "i" ;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With