I just found the answer to this in another Stack Overflow question's answer.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Basically, you need to extend the existing window
interface to tell it about your new property.
Index types
It is possible to denote obj
as any
, but that defeats the whole purpose of using typescript. obj = {}
implies obj
is an Object
. Marking it as any
makes no sense. To accomplish the desired consistency an interface could be defined as follows.
interface LooseObject {
[key: string]: any
}
var obj: LooseObject = {};
OR to make it compact:
var obj: {[k: string]: any} = {};
LooseObject
can accept fields with any string as key and any
type as value.
obj.prop = "value";
obj.prop2 = 88;
The real elegance of this solution is that you can include typesafe fields in the interface.
interface MyType {
typesafeProp1?: number,
requiredProp1: string,
[key: string]: any
}
var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number
obj.prop = "value";
obj.prop2 = 88;
Record<Keys,Type>
utility type
Update (August 2020): @transang brought this up in comments
Record<Keys,Type>
is a Utility type in typescript. It is a much cleaner alternative for key-value pairs where property-names are not known.
It's worth noting that Record<Keys,Type>
is a named alias to {[k: Keys]: Type}
where Keys
and Type
are generics.
IMO, this makes it worth mentioning here
For comparison,
var obj: {[k: string]: any} = {};
becomes
var obj: Record<string,any> = {}
MyType
can now be defined by extending Record type
interface MyType extends Record<string,any> {
typesafeProp1?: number,
requiredProp1: string,
}
While this answers the Original question, the answer here by @GreeneCreations might give another perspective on how to approach the problem.
Best Answer
Configure:
If you're using VS code (or if you see a
tsconfig.json
file):You should add the
lib
property to yourtsconfig.json
and then your editor will use the bundled typescript type definitions and also give you intellisense.Just add the
"lib": ["esnext", "dom"]
to yourtsconfig.json
and restart VS CodeSee all
tsconfig.json
options here.If you're using Visual Studio or MSBuild include this tag:
See all MSBuild typescript compiler options and usage here.
Check your work:
If you've configured your project to use the built-in types and restarted your editor, then your resulting type will look like this instead of the type being
any
when you useObject.assign
:Note on polyfills and older browser compatibility:
If you'd like to include the polyfills (which you should) then I would recommend using core-js's polyfills.
or
Then in the entry point in your app (e.g.
/src/index.ts
) add the import forcore-js
at the top of the file:If you're not using a package manager then you can just paste the following polyfill taken from MDN in some place in your code that runs before the your usage of
Object.assign
.