Aktualizacja 2019-05-15 (ulepszony wzorzec kodu jako alternatywa)
Po wielu latach używania const
i korzystania z bardziej funkcjonalnego kodu, w większości przypadków odradzam korzystanie z poniższych. (Podczas budowania obiektów zmuszanie systemu typów do określonego typu zamiast pozwalania mu na wnioskowanie o typach często oznacza, że coś jest nie tak).
Zamiast tego zaleciłbym użycie const
zmiennych w jak największym stopniu, a następnie skomponowanie obiektu jako ostatni krok:
const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
- Spowoduje to prawidłowe wpisanie wszystkiego bez potrzeby wyraźnego pisania.
- Nie ma potrzeby ponownego wpisywania nazw pól.
- To prowadzi do najczystszego kodu z mojego doświadczenia.
- Dzięki temu kompilator może zapewnić większą weryfikację stanu (na przykład, jeśli powrócisz w wielu lokalizacjach, kompilator zapewni, że zawsze będzie zwracany ten sam typ obiektu - co zachęca cię do zadeklarowania całej wartości zwracanej w każdej pozycji - dając całkowicie jasne zamiar tej wartości).
Dodanie 2020-02-26
Jeśli rzeczywiście potrzebujesz typu, który możesz leniwie zainicjować: Zaznacz, że jest to typ unii zerowej (null lub Type). System typów uniemożliwi korzystanie z niego bez uprzedniego upewnienia się, że ma wartość.
W tsconfig.json
upewnij się, że włączono ścisłe kontrole zerowe:
"strictNullChecks": true
Następnie użyj tego wzorca i pozwól systemowi typów zabezpieczyć cię przed przypadkowym zerowym / niezdefiniowanym dostępem:
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
}
}
Nie wykonuj poniższych czynności w 99% przypadków:
Aktualizacja 2016-02-10 - Aby obsłużyć TSX (Dzięki @Josh)
Użyj as
operatora dla TSX.
var obj = {
property: null as string
};
Dłuższy przykład:
var call = {
hasStarted: null as boolean,
hasFinished: null as boolean,
id: null as number,
};
Oryginalna odpowiedź
Użyj operatora rzutowania, aby uczynić to zwięzłym (przez ustawienie wartości null na żądany typ).
var obj = {
property: <string> null
};
Dłuższy przykład:
var call = {
hasStarted: <boolean> null,
hasFinished: <boolean> null,
id: <number> null,
};
Jest to o wiele lepsze niż posiadanie dwóch części (jedna do deklarowania typów, druga do deklarowania wartości domyślnych):
var callVerbose: {
hasStarted: boolean;
hasFinished: boolean;
id: number;
} = {
hasStarted: null,
hasFinished: null,
id: null,
};