Reputation: 1109
Is it possible to do a type annotation for a specific property when initialising an object in Typescript?
In my case I have a template literal type
type ID = `book#${string}`;
and I want to make sure that when I create an object (which needs to be of type Record<string, any>, so I cannot enforce type there):
const a = {
id: `book#abc` # Should be fine
}
that there is a lint / compile time error if I write for example
const a = {
id: `car#abc` # Should NOT be fine
}
I am looking for something along the lines of
const a = {
id: `book#abc` as ID
}
but that would just assume (assert?) that the id is correct.
The only solution I have found is to create a function
function asId(x: ID): ID {
return x;
}
which I don't find very nice.
Upvotes: 1
Views: 407
Reputation: 1074485
This answer might violate this constraint
...which needs to be of type
Record<string, any>
, so I cannot enforce type there...
but I don't think so (details below).
You could define a WithID
type like this:
type WithID = {id: ID} & Record<string, any>;
That enforces the requirement on id
while allowing other properties:
const a: WithID = {
id: `book#abc`, // Works
whatever: 42,
};
const b: WithID = {
id: `car#abc`, // Type error
whatever: 42,
};
The reason I don't think it violates the constraint I quoted above is that a
and b
can be used anywhere a Record<string, any>
can be used. Example:
function usageExample(o: Record<string, any>) {
console.log(o);
}
usageExample(a); // Works
// And
const c: Record<string, any> = a; // Works
So the id
being "tighter" really just applies to the object literal you're assigning.
Upvotes: 1