Reputation: 729
This piece of Typescript:
enum Field {
age,
bugs,
}
interface Foo {
number_age: number;
number_bugs: number;
}
function makeFoo():Foo {
let ret = {};
let i = 0;
for (let key in Field) {
ret['number_'+key] = i++;
}
return ret;
}
throws this error when compiling:
$ tsc test.ts
test.ts(16,5): error TS2322: Type '{}' is not assignable to type 'Foo'.
Property 'number_age' is missing in type '{}'.
But ret
will definitely have a number_age
property at runtime. How do I either trick the compiler into knowing that number_age
and number_bugs
will be there or otherwise change my code so that it compiles?
Upvotes: 1
Views: 2124
Reputation: 7360
You can define that ret
will be a Foo
element using the keyword as
enum Field {
age,
bugs,
}
interface Foo {
number_age: number;
number_bugs: number;
}
function makeFoo():Foo {
let ret = {} as Foo;
let i = 0;
for (let key in Field) {
ret['number_'+key] = i++;
}
return ret;
}
Read the documentation about type assertions:
Sometimes you’ll end up in a situation where you’ll know more about a value than TypeScript does. Usually this will happen when you know the type of some entity could be more specific than its current type.
Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler. TypeScript assumes that you, the programmer, have performed any special checks that you need.
Type assertions have two forms. One is the “angle-bracket” syntax:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
And the other is the as-syntax:
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
The two samples are equivalent. Using one over the other is mostly a choice of preference; however, when using TypeScript with JSX, only as-style assertions are allowed.
Upvotes: 2
Reputation: 1080
you should use casting operator <TYPE>
enum Field {
age,
bugs,
}
interface Foo {
number_age: number;
number_bugs: number;
}
function makeFoo():Foo {
let ret = {};
let i = 0;
for (let key in Field) {
ret['number_'+key] = i++;
}
return <Foo>ret; // Here
}
Upvotes: 0
Reputation: 221302
You're pretty far off the rails here (you're going to also make number_0
and number_1
properties on Foo
, is this intended?) so it's going to be more work than its worth to "properly" typecheck this code. Just use any
:
function makeFoo():Foo {
let ret: any = {};
let i = 0;
for (let key in Field) {
ret['number_'+key] = i++;
}
return ret;
}
Upvotes: 0