How can I specify a typed object literal in TypeScript?
Answer is to use the identity function:
function to<T>(value: T): T { return value; }
const instance = to<MyInfo>({
value: 1,
name: 'Hey!',
});
there should be no performance impact for an unnecessary call the to
function, it should be optimized away by the JIT compiler
UPDATED on Sept 22, 2022:
At last TypeScript team made a tool for it:
const instance = { value: 1, name: 'Hey!' } satisfies MyInfo;
Read more: https://github.com/microsoft/TypeScript/issues/47920
Intellisense for members of object literals is provided by the contextual type (see section 4.19 of the spec) of the expression.
You can acquire a contextual type in a variety of ways. Some of the most common places where a contextual type is applied are:
- The initializer of a variable with a type annotation
- The expression in a
return
statement in a function or getter with a return type annotation - The expression in a type assertion expression (
<T>expr
)
In your example, you can use a type assertion to force your object literal to have a contextual type:
function testB() {
return <IMyInfo>{ name: 'Hey!' };
}
Remember that that interfaces follow duck typing: if an object looks like it matches the interface, it does match the interface.
So
function testB(): IBaseInfo = {
return { name: 'Hey!' };
}
is exactly the same as
function testA(): IBaseInfo = {
var result: IMyInfo = { name: 'Hey!' };
return result;
}
Either way, the returned object looks like an IMyInfo, so it is an IMyInfo. Nothing that happens inside the function affects what interfaces it matches.
However, in your examples, the return value of the function is IBaseInfo, so the compiler and intellisense will assume that the object is just an IBaseInfo. if you want the caller of the function to know that the return value is an IMyInfo, you need to make the return value of the function IMyInfo:
function testB(): IMyInfo = {
return { name: 'Hey!' };
}
or using type inference, simply
function testB() = {
return { name: 'Hey!' };
}