Update 2019-05-15 (Improved Code Pattern as Alternative)
After many years of using const and benefiting from more functional code, I would recommend against using my original answers in most cases (the headings below this section i.e. when building objects, forcing the type system into a specific type instead of letting it infer types is often an indication that something is wrong).
Instead I would recommend using const variables as much as possible and then compose the object as the final step:
const id = getId(); const hasStarted = true; ... const hasFinished = false; ... return { hasStarted, hasFinished, id };
- This will properly type everything without any need for explicit typing.
- There is no need to retype the field types.
- This leads to the cleanest code from my experience.
- This allows the compiler to provide more state verification (for example, if you return in multiple locations, the compiler will ensure the same type of object is always returned - which encourages you to declare the whole return value at each position - giving a perfectly clear intention of that value).
Bonus: Optional Fields 2022-09-29
const id = getId(); const optionalField = getOptionalValue(); return { id, // This will always exist as a key in the object but it might be undefined optionalField, // This will only exist as a key in the object if it has a truthy value ...optionalField2 ? { optionalField } : {}, // This will only exist as a key in the object if it is not null or undefined ...optionalField2 != null ? { optionalField } : {}, };
Addition 2020-02-26
If you do actually need a type that you can be lazily initialized: Mark it is a nullable union type (null or Type). The type system will prevent you from using it without first ensuring it has a value.
In tsconfig.json, make sure you enable strict null checks:
"strictNullChecks": true
Then use this pattern and allow the type system to protect you from accidental null/undefined access:
const state = { instance: null as null | ApiService, // OR // instance: undefined as undefined | ApiService, }; const useApi = () => { // If I try to use it here, the type system requires a safe way to access it // Simple lazy-initialization const api = state?.instance ?? (state.instance = new ApiService()); api.fun(); // Also here are some ways to only access it if it has value: // The 'right' way: Typescript 3.7 required state.instance?.fun(); // Or the old way: If you are stuck before Typescript 3.7 state.instance && state.instance.fun(); // Or the long winded way because the above just feels weird if (state.instance) { state.instance.fun(); } // Or the I came from C and can't check for nulls like they are booleans way if (state.instance != null) { state.instance.fun(); } // Or the I came from C and can't check for nulls like they are booleans // AND I was told to always use triple === in javascript even with null checks way if (state.instance !== null && state.instance !== undefined) { state.instance.fun(); } }; class ApiService { fun() { // Do something useful here } }
Do not do the below in 99% of cases:
Update 2016-02-10 - To Handle TSX (Thanks @Josh)
Use the as operator for TSX.
var obj = { property: null as string };
A longer example:
var call = { hasStarted: null as boolean, hasFinished: null as boolean, id: null as number, };
Original Answer
Use the cast operator to make this succinct (by casting null to the desired type).
var obj = { property: <string> null };
A longer example:
var call = { hasStarted: <boolean> null, hasFinished: <boolean> null, id: <number> null, };
This is much better than having two parts (one to declare types, the second to declare defaults):
var callVerbose: { hasStarted: boolean; hasFinished: boolean; id: number; } = { hasStarted: null, hasFinished: null, id: null, };