Nie mogę dowiedzieć się, jak ustawić domyślne wartości właściwości dla moich składników za pomocą Typescript.
Oto kod źródłowy:
class PageState
{
}
export class PageProps
{
foo: string = "bar";
}
export class PageComponent extends React.Component<PageProps, PageState>
{
public render(): JSX.Element
{
return (
<span>Hello, world</span>
);
}
}
A kiedy spróbuję użyć komponentu w ten sposób:
ReactDOM.render(<PageComponent />, document.getElementById("page"));
Pojawia się błąd informujący, że foo
brakuje właściwości . Chcę użyć wartości domyślnej. Próbowałem również użyć static defaultProps = ...
wewnątrz komponentu, ale nie przyniosło to efektu, jak podejrzewałem.
src/typescript/main.tsx(8,17): error TS2324: Property 'foo' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...'.
Jak mogę użyć domyślnych wartości właściwości? Wiele komponentów JS, których używa moja firma, opiera się na nich i ich niestosowanie nie jest wyborem.
reactjs
typescript
tsx
Tomek
źródło
źródło
static defaultProps
jest poprawne. Czy możesz wysłać ten kod?Odpowiedzi:
Domyślne rekwizyty z komponentem klasy
Używanie
static defaultProps
jest poprawne. Powinieneś także używać interfejsów, a nie klas, dla właściwości i stanu.Aktualizacja 2018/12/1 : TypeScript poprawił sprawdzanie typów związane z
defaultProps
upływem czasu. Czytaj dalej, aby poznać najnowsze i najlepsze zastosowania, aż do starszych zastosowań i problemów.W przypadku języka TypeScript 3.0 i nowszych
Specjalnie dodano obsługę
defaultProps
języka TypeScript, aby sprawdzanie typów działało zgodnie z oczekiwaniami. Przykład:Które można renderować i kompilować bez przekazywania
foo
atrybutu:Zauważ, że:
foo
nie jest oznaczony jako opcjonalny (tj.foo?: string
), mimo że nie jest wymagany jako atrybut JSX. Oznaczenie jako opcjonalne oznaczałoby, że tak może byćundefined
, ale w rzeczywistości nigdy tak nie będzie,undefined
ponieważdefaultProps
zapewnia wartość domyślną. Pomyśl o tym podobnie do tego , jak możesz oznaczyć parametr funkcji jako opcjonalny lub jako wartość domyślną, ale nie obie, ale oba oznaczają, że wywołanie nie musi określać wartości . TypeScript 3.0+ traktujedefaultProps
w podobny sposób, co jest naprawdę fajne dla użytkowników Reacta!defaultProps
ma wyraźnej adnotacji typu. Jego typ jest wywnioskowany i używany przez kompilator do określenia, które atrybuty JSX są wymagane. Możesz użyć,defaultProps: Pick<PageProps, "foo">
aby zapewnićdefaultProps
dopasowanie podzbioruPageProps
. Więcej informacji na temat tego zastrzeżenia wyjaśniono tutaj .@types/react
wersji16.4.11
do prawidłowego działania.Dla TypeScript 2.1 do 3.0
Przed zaimplementowaniem obsługi kompilatora TypeScript 3.0
defaultProps
nadal można było z niego korzystać i działało w 100% z React w czasie wykonywania, ale ponieważ TypeScript uwzględniał właściwości tylko podczas sprawdzania atrybutów JSX, musiałbyś oznaczyć właściwości, które mają wartości domyślne, jako opcjonalne?
. Przykład:Zauważ, że:
defaultProps
zPartial<>
tak, że typu kontrole przeciw rekwizytów, ale nie trzeba dostarczyć wszelkich wymaganych własności o wartości domyślnej, która nie ma sensu, ponieważ wymagane właściwości nie powinny potrzebować domyślną.strictNullChecks
z wartościthis.props.foo
będziepossibly undefined
i wymagać potwierdzenia niezerowego (tj.this.props.foo!
) Lub zabezpieczenia typu (tj.if (this.props.foo) ...
) Do usunięciaundefined
. Jest to denerwujące, ponieważ domyślna wartość właściwości oznacza, że w rzeczywistości nigdy nie będzie ona niezdefiniowana, ale TS nie zrozumiał tego przepływu. To jeden z głównych powodów, dla których TS 3.0 dodał wyraźne wsparcie dladefaultProps
.Przed TypeScript 2.1
Działa to tak samo, ale nie masz
Partial
typów, więc po prostu pomińPartial<>
i albo podaj domyślne wartości dla wszystkich wymaganych właściwości (nawet jeśli te domyślne nigdy nie będą używane) lub całkowicie pomiń jawną adnotację typu.Domyślne rekwizyty z komponentami funkcjonalnymi
Możesz również użyć
defaultProps
na składnikach funkcji, ale musisz wpisać swoją funkcję w interfejsieFunctionComponent
(StatelessComponent
w@types/react
poprzedniej wersji16.7.2
), aby TypeScript wiedział odefaultProps
funkcji:Zauważ, że nie musisz
Partial<PageProps>
nigdzie używać, ponieważFunctionComponent.defaultProps
jest już określony jako częściowy w TS 2.1+.Inną fajną alternatywą (właśnie tego używam) jest zniszczenie
props
parametrów i bezpośrednie przypisanie wartości domyślnych:Wtedy wcale nie potrzebujesz
defaultProps
! Należy pamiętać, że jeśli nie dostarczajądefaultProps
na składnik funkcji będzie mieć pierwszeństwo przed wartościami parametrów domyślnych, bo React zawsze wyraźnie przekazaćdefaultProps
wartości (tak parametry nie są niezdefiniowane, więc parametr domyślny jest nie używany). Tak byłoby użyć jeden lub drugi, nie oba.źródło
<PageComponent>
gdzieś bez przekazywania właściwościfoo
. Możeszfoo?: string
ustawić to jako opcjonalne, używając w swoim interfejsie.public static defaultProps
lubstatic defaultProps
(public
jest to ustawienie domyślne), aby wszystko (kompilator i środowisko uruchomieniowe React) działało poprawnie. Może działać w czasie wykonywaniaprivate static defaultProps
tylko z boprivate
ipublic
nie istnieje w czasie wykonywania, ale kompilator nie działałby poprawnie.W przypadku Typescript 2.1+ użyj Partial <T> zamiast ustawiania właściwości interfejsu jako opcjonalnych.
źródło
Dzięki Typescript 3.0 jest nowe rozwiązanie tego problemu:
Zauważ, że aby to zadziałało, potrzebujesz nowszej wersji
@types/react
niż16.4.6
. Działa z16.4.11
.źródło
export interface Props { name?: string;}
gdzie nazwa jest opcjonalnym rekwizytem? Ciągle dostajęTS2532 Object is possibly 'undefined'
undefined
jest to rodzaj automatycznej wartości domyślnej dla tych właściwości. Chceszundefined
czasami przekazać jako jawną wartość, ale masz inną wartość domyślną? Czy próbowałeśexport interface Props {name: string | undefined;}
zamiast tego? Nie próbowałem tego, tylko pomysł.?
jest tym samym, co dodawanie|undefined
. Chcę opcjonalnie przekazać propozycję i niechdefaultProps
zajmiemy się tym przypadkiem. Wygląda na to, że nie jest to jeszcze możliwe w TS3. Ja po prostu bał użyćname!
składni, ponieważ wiem, że nigdy nie maundefined
, gdydefaultProps
są ustawione. W każdym razie dzięki!Dla tych, którzy mają opcjonalne właściwości, które wymagają wartości domyślnych. Kredyt tutaj :)
źródło
Z komentarza @pamelus do zaakceptowanej odpowiedzi:
Właściwie możesz użyć dziedziczenia interfejsu Typescript . Wynikowy kod jest tylko trochę bardziej szczegółowy.
źródło
W przypadku komponentu funkcjonalnego wolałbym zachować
props
argument, więc oto moje rozwiązanie:źródło
Komponent funkcjonalny
Właściwie dla komponentu funkcjonalnego najlepsza praktyka jest jak poniżej, tworzę przykładowy komponent Spinner:
źródło