Typescript: الدعائم الافتراضية لا تعمل في المكون الوظيفي

تم إنشاؤها على ٤ مايو ٢٠١٩  ·  16تعليقات  ·  مصدر: microsoft/TypeScript

إصدار TypeScript: 3.4.5

مصطلحات البحث:
رد فعل الدعائم الافتراضية defaultProps مكون وظيفي عديم الحالة

الشفرة

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" />;

سلوك متوقع:
وفقًا لملاحظات إصدار TypeScript 3.0 ، يجب ألا تكون optional مطلوبة في Test حيث تم تحديدها افتراضيًا باستخدام ميزة التهيئة الافتراضية ES2015 في Component .

السلوك الفعلي:
تم طرح خطأ الترجمة التالي:

الخاصية 'اختيارية' مفقودة في النوع '{name: string؛ } 'ولكنه مطلوب في النوع "Props".

رابط الملعب:
حلقة الوصل
لا يبدو أن الملعب يدعم TSX.

القضايا ذات الصلة:

27425

Question

التعليق الأكثر فائدة

باستخدام TypeScript 3.1 أو أعلى ، يجب أن تكون قادرًا على كتابة:

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

ال 16 كومينتر

قد لا تكون الوثائق واضحة حول هذا الأمر ، ولكن عليك وضع علامة على الخاصية على أنها اختيارية في واجهة Props :

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

يبدو أن هذا لا يتطابق مع ما تقوله ملاحظات الإصدار:

export interface Props {
    name: string;
}

// ...

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

يعني جعل الخاصية اختيارية أيضًا أنه عند الوصول إلى الخاصيات خارج المكون (في الاختبار) ، لا يضمن نظام النوع وجود الخاصية على الرغم من وجودها دائمًا.

مثال:

const wrapper = shallow(<Test/>);

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

إذا كانت optional دالة ، فسيتعين عليك التحقق من وجودها قبل تنفيذها. مثال على ذلك ، إذا قمت بتوفير خاصية onClick الافتراضية التي تستدعي فقط preventDefault .

باستخدام TypeScript 3.1 أو أعلى ، يجب أن تكون قادرًا على كتابة:

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

هل من الخطأ أن استخدام ميزة المُهيئ الافتراضية لا يعمل مع الدعائم الافتراضية؟ يبدو أنه انحدار نظرًا لأن المثال الوارد في ملاحظات الإصدار لا يعمل على أحدث إصدار من TypeScript.

tbassetto المشكلة في ذلك هي أن TS لا يجبرك فعليًا على تقديم قيمة افتراضية:

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 />;

الشيء المزعج الآخر هو حقيقة أنه يجب عليك القيام بذلك في المقام الأول: إذا قمت بكتابة Comp كـ React.FC<Props> ، فسيتم كتابة defaultProps بشكل جيد ، ولكن تظهر مشاكل أخرى .

بشكل عام ، يبدو أن دعم TypeScripts JSX / React في الوقت الحالي في حالة غريبة ليست مثالية تمامًا ، ولكن يبدو أن كل شيء على ما يرام (على الأقل في عيني - بشكل أساسي ، لا يمكنني العثور على أي شيء ثابت ملاحظات حول الطريقة "الرسمية" الحالية لعمل مكونات React عديمة الحالة بطريقة آمنة من النوع لـ 3.4.5).

على الرغم من أنني أرى كل شخص يشير إلى العمل في الجوار ، إلا أنني غير قادر على جعل أي منهم يعمل.

أنا في الإصدار 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;

هل لدى أي شخص أي فكرة عن سبب استمرار هذا في إلقاء الخطأ

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

لقد جربت جميع الإصلاحات المقترحة في # 27425 و # 519 أيضًا.

tomspeak إما الحل البديل الخاص بي أو مشكلة Hotell (على الرغم من أن هذا

على الرغم من أنني أرى كل شخص يشير إلى العمل في الجوار ، إلا أنني غير قادر على جعل أي منهم يعمل.

أنا في الإصدار 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;

هل لدى أي شخص أي فكرة عن سبب استمرار هذا في إلقاء الخطأ

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

لقد جربت جميع الإصلاحات المقترحة في # 27425 و # 519 أيضًا.

تحتاج فقط إلى جعل shouldTruncateContent: منطقية؛ اختياري shouldTruncateContent?: boolean;

قد لا تكون الوثائق واضحة حول هذا الأمر ، ولكن عليك وضع علامة على الخاصية على أنها اختيارية في واجهة Props :

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

أنا أستخدم هذا النوع الاختياري في كل مكان. لماذا التصويت لأسفل؟ هل يمكن لأحد أن يشرح؟

ralexhassle ، لا يمكنني شرح
قد تفضل استخدام defaultProps ، والذي لا يستخدمه مثال السؤال ، ولكن بقدر ما أشعر بالقلق ، فإن وضع علامة على الخصائص الاختيارية على أنها اختيارية ربما يكون جيدًا تمامًا ...

الغرض من المشكلة هو أن الخاصيات ليست اختيارية ، ولكن لها قيمة افتراضية (لذلك يمكن تجنبها عند استخدام المكون). إذا قمت بتمييز العنصر الاختياري بـ ? فإن TS يفترض أنه قد يكون غير معرّف ويفرض عليك التعامل مع هذه الحالة. ومع ذلك ، لن يتم إلغاء تعريفه أبدًا نظرًا لوجود قيمة افتراضية. يعود سبب التصويت إلى أن المعلق لم يفهم المشكلة واقترح شيئًا يتعارض مع ملاحظات الإصدار 3.0.

RyanCavanaugh لماذا

ربما فاتني ولكني لا أرى إجابة فعلية ، على الرغم من الكثير من الحلول؟

ملاحظة: استخدام TypeScript v4

يمكنك القيام بذلك بهذه الطريقة ، هنا الخصائص في Props هي المعلمة الاختيارية والمستخدمة بشكل أكبر في المكون.

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 الغرض من هذه المشكلة هو تجنب تمييز نوع الدعامة على أنه اختياري.

لم أتمكن من الحصول على وسيطات افتراضية للوظيفة أو مقترحات أخرى لكتابة التحقق بشكل صحيح. الحل العملي الوحيد الذي تمكنت من العثور عليه هو:

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" />;

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

siddjain picture siddjain  ·  3تعليقات

kyasbal-1994 picture kyasbal-1994  ·  3تعليقات

Roam-Cooper picture Roam-Cooper  ·  3تعليقات

bgrieder picture bgrieder  ·  3تعليقات

wmaurer picture wmaurer  ·  3تعليقات