Não consigo descobrir como definir valores de propriedade padrão para meus componentes usando o Typecript.
Este é o código fonte:
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>
);
}
}
E quando tento usar o componente assim:
ReactDOM.render(<PageComponent />, document.getElementById("page"));
Recebo um erro dizendo que a propriedade foo
está ausente. Eu quero usar o valor padrão. Eu também tentei usar static defaultProps = ...
dentro do componente, mas não teve efeito como eu suspeitava.
src/typescript/main.tsx(8,17): error TS2324: Property 'foo' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...'.
Como posso usar valores de propriedade padrão? Muitos componentes JS que minha empresa usa dependem deles e não usá-los não é uma escolha.
reactjs
typescript
tsx
Tom
fonte
fonte
static defaultProps
está correto. Você pode postar esse código?Respostas:
Adereços padrão com componente de classe
O uso
static defaultProps
está correto. Você também deve usar interfaces, não classes, para props e state.Atualização 2018/12/1 : O TypeScript aprimorou a verificação de tipo relacionada ao
defaultProps
longo do tempo. Continue lendo para obter o melhor e mais recente uso, para usos e problemas mais antigos.Para TypeScript 3.0 e superior
O TypeScript adicionou suporte
defaultProps
especificamente para fazer com que a verificação de tipo funcionasse como você esperaria. Exemplo:Que pode ser renderizado e compilado sem passar um
foo
atributo:Observe que:
foo
não está marcado como opcional (ou sejafoo?: string
), mesmo que não seja necessário como um atributo JSX. Marcar como opcional significaria que poderia serundefined
, mas na verdade nunca seráundefined
porquedefaultProps
fornece um valor padrão. Pense nisso de maneira semelhante a como você pode marcar um parâmetro de função como opcional ou com um valor padrão, mas não ambos, mas ambos significam que a chamada não precisa especificar um valor . O TypeScript 3.0+ trata dedefaultProps
maneira semelhante, o que é realmente interessante para os usuários do React!defaultProps
não tem nenhum tipo de anotação explícita. Seu tipo é inferido e usado pelo compilador para determinar quais atributos JSX são necessários. Você pode usardefaultProps: Pick<PageProps, "foo">
para garantir adefaultProps
correspondência de um subconjunto dePageProps
. Mais sobre esta ressalva é explicada aqui .@types/react
versão16.4.11
funcione corretamente.Para TypeScript 2.1 até 3.0
Antes que o TypeScript 3.0 implementasse o suporte ao compilador,
defaultProps
você ainda podia usá-lo, e funcionava 100% com o React em tempo de execução, mas como o TypeScript considerava apenas adereços na verificação de atributos JSX, seria necessário marcar adereços com padrões como opcionais?
. Exemplo:Observe que:
defaultProps
comPartial<>
para que ele digita-cheques contra seus adereços, mas você não tem que fornecer a cada propriedade necessária com um valor padrão, que não faz sentido uma vez que as propriedades necessárias não deve nunca precisa de um padrão.strictNullChecks
o valor dethis.props.foo
serápossibly undefined
e será necessária uma asserção não nula (isto éthis.props.foo!
) ou uma proteção de tipo (isto é,if (this.props.foo) ...
) para removerundefined
. Isso é irritante, uma vez que o valor padrão do suporte significa que ele nunca será indefinido, mas o TS não entendeu esse fluxo. Essa é uma das principais razões pelas quais o TS 3.0 adicionou suporte explícitodefaultProps
.Antes do TypeScript 2.1
Isso funciona da mesma forma, mas você não tem
Partial
tipos, portanto, omitaPartial<>
e forneça os valores padrão para todos os adereços necessários (mesmo que esses padrões nunca sejam usados) ou omita completamente a anotação de tipo explícita.Adereços padrão com componentes funcionais
Você também pode usar os
defaultProps
componentes da função, mas é necessário digitar sua função na interfaceFunctionComponent
(StatelessComponent
na@types/react
versão anterior16.7.2
) para que o TypeScript conheçadefaultProps
a função:Observe que você não precisa usá-lo em
Partial<PageProps>
nenhum lugar porqueFunctionComponent.defaultProps
já está especificado como parcial no TS 2.1+.Outra boa alternativa (é isso que eu uso) é desestruturar seus
props
parâmetros e atribuir valores padrão diretamente:Então você não precisa de
defaultProps
nada! Esteja ciente de que se você não fornecerdefaultProps
em um componente função que ele terá precedência sobre valores de parâmetros padrão, porque Reagir sempre explicitamente passar osdefaultProps
valores (para os parâmetros nunca são indefinido, assim, o parâmetro padrão nunca é utilizado.) Então você usaria um ou outro, não ambos.fonte
<PageComponent>
algum lugar sem passar ofoo
suporte. Você pode torná-lo opcional usandofoo?: string
em sua interface.public static defaultProps
oustatic defaultProps
(public
é padrão) para que tudo (compilador e tempo de execução do React) funcione corretamente. Pode funcionar em tempo de execuçãoprivate static defaultProps
apenas porque,private
epublic
não existe, mas o compilador não funcionaria corretamente.Com o TypeScript 2.1+, use Parcial <T> em vez de tornar suas propriedades de interface opcionais.
fonte
Com o TypeScript 3.0, há uma nova solução para esse problema:
Observe que, para que isso funcione, você precisa de uma versão mais recente do
@types/react
que16.4.6
. Trabalha com16.4.11
.fonte
export interface Props { name?: string;}
onde name é um acessório opcional ? Eu continuo recebendoTS2532 Object is possibly 'undefined'
undefined
é um tipo de valor padrão automático para esses acessórios. Você deseja passarundefined
como valor explícito às vezes, mas tem outro valor padrão? Você já tentouexport interface Props {name: string | undefined;}
? Ainda não tentei isso, apenas uma ideia.?
é o mesmo que adicionar|undefined
. Quero opcionalmente passar o suporte e deixardefaultProps
lidar com esse caso. Parece que isso ainda não é possível no TS3. Vou usar a temidaname!
sintaxe, pois sei que nunca éundefined
quandodefaultProps
estão definidas. Obrigado de qualquer forma!Para aqueles que possuem adereços opcionais que precisam de valores padrão. Crédito aqui :)
fonte
De um comentário de @pamelus na resposta aceita:
Na verdade, você pode usar a herança de interface do Typescript . O código resultante é apenas um pouco mais detalhado.
fonte
Para o componente funcional, prefiro manter o
props
argumento, então aqui está minha solução:fonte
Componente funcional
Na verdade, para o componente funcional, a melhor prática é como abaixo, eu crio um componente Spinner de exemplo:
fonte