In TypeScript classes it\'s possible to declare types for properties, for example:
class className {
property: string;
};
How do declare
After many years of using const and benefiting from more functional code, I would recommend against using the below in most cases. (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};
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
}
}
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,
};
Use the cast operator to make this succinct (by casting null to the desired type).
var obj = {
property: null
};
A longer example:
var call = {
hasStarted: null,
hasFinished: null,
id: 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,
};