Typescript: Alat peraga default tidak berfungsi di komponen fungsional

Dibuat pada 4 Mei 2019  ·  16Komentar  ·  Sumber: microsoft/TypeScript

TypeScript Version: 3.4.5

Istilah Pencarian:
react default props defaultProps fungsional komponen stateless

Kode

import React from "react";

interface Props {
  name: string;
  optional: string;
}

const Component = ({ name, optional = "default" }: Props) => (
  <p>{name + " " + optional}</p>
);

const Test = () => <Component name="test" />;

Perilaku yang diharapkan:
Menurut catatan rilis TypeScript 3.0 , optional prop tidak boleh dibutuhkan dalam Test karena telah ditentukan dengan default menggunakan fitur penginisialisasi default ES2015 di Component .

Perilaku sebenarnya:
Kesalahan kompilasi berikut muncul:

Properti 'opsional' tidak ada di tipe '{name: string; } 'tetapi dibutuhkan dalam tipe' Props '.

Tautan Taman Bermain:
Tautan
Sepertinya taman bermain tidak mendukung TSX.

Masalah Terkait:

27425

Question

Komentar yang paling membantu

Dengan TypeScript 3.1 atau lebih tinggi Anda harus dapat menulis:

export interface Props {
    name: string;
}

function Greet(props: Props) {
    return <div>Hello {props.name.toUpperCase()}!</div>;
}
Greet.defaultProps = {
  name: "world",
} as Partial<Props>; // Good practice, without it you could use a number as default prop and TypeScript wouldn't complain…

const component = <Greet />; // no errors

Semua 16 komentar

Dokumentasi mungkin tidak jelas tentang ini, tetapi Anda harus menandai properti sebagai opsional di antarmuka Props :

interface Props {
    name: string;
    optional?: string;
}

Itu sepertinya tidak cocok dengan apa yang dikatakan catatan rilis:

export interface Props {
    name: string;
}

// ...

function Greet({ name = "world" }: Props) {
    return <div>Hello {name.toUpperCase()}!</div>;
}

Membuat prop opsional juga berarti bahwa ketika Anda mengakses props di luar komponen (dalam pengujian), sistem tipe tidak menjamin bahwa prop itu ada meskipun itu akan selalu ada.

Contoh:

const wrapper = shallow(<Test/>);

// optional is string | undefined instead of string
const optional = wrapper
        .find(Component)
        .props()
        .optional;

Jika optional adalah sebuah fungsi, Anda harus memeriksa keberadaannya sebelum Anda menjalankannya. Contohnya adalah jika Anda memberikan onClick prop default yang hanya memanggil preventDefault .

Dengan TypeScript 3.1 atau lebih tinggi Anda harus dapat menulis:

export interface Props {
    name: string;
}

function Greet(props: Props) {
    return <div>Hello {props.name.toUpperCase()}!</div>;
}
Greet.defaultProps = {
  name: "world",
} as Partial<Props>; // Good practice, without it you could use a number as default prop and TypeScript wouldn't complain…

const component = <Greet />; // no errors

Apakah bug yang menggunakan fitur penginisialisasi default tidak berfungsi untuk properti default? Tampaknya seperti regresi karena contoh yang diberikan dalam catatan rilis tidak berfungsi pada versi TypeScript terbaru.

@tbassetto Masalahnya adalah TS tidak memaksa Anda untuk benar-benar memberikan nilai default:

import React from 'react';

interface Props {
  myProp: string;
}

const Comp = (props: Props) => {
  return (
    <div>
      {props.myProp.toUpperCase()}
    </div>
  );
};

Comp.defaultProps = {

} as Pick<Props, 'myProp'>;

const comp = <Comp />;

Hal lain yang mengganggu adalah kenyataan bahwa Anda harus melakukan ini sejak awal: Jika saya mengetik Comp sebagai React.FC<Props> , maka defaultProps diketik dengan baik, tetapi masalah lain muncul .

Secara keseluruhan, dukungan TypeScripts JSX / React saat ini tampaknya berada dalam keadaan "tidak cukup sempurna" yang aneh, tetapi berjalan seolah-olah semuanya baik-baik saja (setidaknya di mata saya - Terutama, saya tidak dapat menemukan yang solid catatan tentang cara "Resmi" saat ini untuk melakukan komponen React stateless dengan cara yang aman untuk 3.4.5).

Meskipun saya melihat semua orang mereferensikan pekerjaan sekitar, saya tidak dapat membuat salah satu dari mereka bekerja.

Saya menggunakan versi 3.3.3

export interface Props {
  shouldTruncateContent: boolean;
}

const Alert: React.FunctionComponent<Props> = ({
  children,
  shouldTruncateContent = false
}) => {
  return (
        <S.Content shouldTruncateContent={shouldTruncateContent} size="fill">
          {children}
        </S.Content>
  );
};

Alert.defaultProps = {
  shouldTruncateContent: false
} as Pick<Props, 'shouldTruncateContent'>;

export default Alert;

Adakah yang punya wawasan mengapa ini masih melempar kesalahan

TS2741: Property 'shouldTruncateContent' is missing in type '{ children: string; }' but required in type 'Props'.

Saya telah mencoba semua perbaikan yang diusulkan di # 27425 dan # 519 juga.

@tomspeak Solusi saya atau @Hotell lebih buruk (meskipun ini membuat semua properti opsional). Diuji pada 3.5 dengan kode sampel Anda.

Meskipun saya melihat semua orang mereferensikan pekerjaan sekitar, saya tidak dapat membuat salah satu dari mereka bekerja.

Saya menggunakan versi 3.3.3

export interface Props {
  shouldTruncateContent: boolean;
}

const Alert: React.FunctionComponent<Props> = ({
  children,
  shouldTruncateContent = false
}) => {
  return (
        <S.Content shouldTruncateContent={shouldTruncateContent} size="fill">
          {children}
        </S.Content>
  );
};

Alert.defaultProps = {
  shouldTruncateContent: false
} as Pick<Props, 'shouldTruncateContent'>;

export default Alert;

Adakah yang punya wawasan mengapa ini masih melempar kesalahan

TS2741: Property 'shouldTruncateContent' is missing in type '{ children: string; }' but required in type 'Props'.

Saya telah mencoba semua perbaikan yang diusulkan di # 27425 dan # 519 juga.

Anda hanya perlu membuat shouldTruncateContent: boolean; opsional shouldTruncateContent?: boolean;

Dokumentasi mungkin tidak jelas tentang ini, tetapi Anda harus menandai properti sebagai opsional di antarmuka Props :

interface Props {
    name: string;
    optional?: string;
}

Saya menggunakan tipe opsional ini di mana-mana. Mengapa tidak memilih? Bisakah seseorang menjelaskan?

@ralexhassle , saya tidak dapat menjelaskan suara yang ditolak, tetapi saya dapat menjelaskan bahwa tentu saja itu cara yang benar untuk mengetik properti opsional komponen.
Anda mungkin lebih suka menggunakan defaultProps , yang contoh pertanyaannya tidak digunakan, tetapi sejauh yang saya ketahui, menandai properti opsional sebagai opsional mungkin baik-baik saja ...

Tujuan dari masalah ini adalah bahwa props tidak opsional, tetapi memiliki nilai default (oleh karena itu dapat dihindari saat menggunakan komponen). Jika Anda menandai prop opsional dengan ? maka TS mengasumsikan itu bisa tidak ditentukan dan memaksa Anda untuk menangani kasus itu. Namun, itu tidak akan pernah tidak ditentukan karena ada nilai default. Suara negatif tersebut karena komentator tampaknya tidak memahami masalah dan mengusulkan sesuatu yang bertentangan dengan catatan rilis 3.0.

@RyanCavanaugh mengapa bot menutup masalah ini?

Mungkin saya melewatkannya tetapi saya tidak melihat jawaban yang sebenarnya, meskipun banyak solusi?

PS: menggunakan TypeScript v4

Anda dapat melakukannya dengan cara ini, di sini properti di Props adalah parameter opsional dan selanjutnya digunakan dalam komponen.

interface Props {
  children: ReactNode;
  properties?: Record<string, unknown>;
}

const defaultProps: Props = {
  children: '',
  properties: {
    marginTop: 32,
    marginLeft: 0,
    marginBottom: 8,
    marginRight: 0,
  },
};

const RadioListLabel: React.FC<Props> = ({
  children,
  properties = defaultProps.properties,
}) => (
  <View
    margin={[
properties ? properties.marginTop : 0
        properties ? properties.marginLeft : 0
        properties ? properties.marginBottom : 0
        properties ? properties.marginRight : 0
      ]}
  >
    <Text size="m" variant="heading2" lineHeight="body">
      {children}
    </Text>
  </View>
  )

@lakhmeranikita Tujuan dari masalah ini adalah untuk menghindari penandaan tipe prop sebagai opsional.

Saya tidak bisa mendapatkan argumen default fungsi atau proposal lain untuk mengetik dengan benar. Satu-satunya solusi yang bisa saya temukan adalah ini:

import React from "react";

type DefaultProps = { optionalProp: number };
type Props = {
  requiredProp: "some_string" | "other_string";
} & DefaultProps;

export const BaseComponent = (props: Props) => {
  const { requiredProp, optionalProp } = props;
  return (
    <div>
      {requiredProp} {optionalProp}
    </div>
  );
};

BaseComponent.defaultProps = {
  optionalProp: 0,
} as Partial<DefaultProps>;

const comp = <BaseComponent requiredProp="some_string" />;

Apakah halaman ini membantu?
0 / 5 - 0 peringkat