Material-ui: خطأ في نوع الكتابة في المكون المُرجع بواسطة withStyles ()

تم إنشاؤها على ٢٨ سبتمبر ٢٠١٧  ·  55تعليقات  ·  مصدر: mui-org/material-ui

عند استخدام withStyles() hoc في الكتابة المطبوعة ، أتلقى الخطأ التالي عند محاولة استخدام المكون الذي تم إرجاعه:

Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{ children?: ReactNode; }> & Reado...'.
  Type '{}' is not assignable to type 'Readonly<WithStyles<"main">>'.
    Property 'classes' is missing in type '{}'.
  • [x] لقد بحثت في قضايا هذا المستودع وأعتقد أن هذه ليست نسخة مكررة.

يبدو أن هذا التغيير في تعريف النوع قد يكون مرتبطًا بهذه المشكلة.

سلوك متوقع

بالنظر إلى رمز المكون App أدناه ، يجب أن أكون قادرًا على استخدام المكون <App /> بدون خطأ النوع كما فعلت في الإصدار 1.0.0-beta.10.

السلوك الحالي

بالنظر إلى رمز المكون App أدناه ، محاولة استخدام نتائج <App /> في الخطأ المذكور أعلاه.

الرمز

import * as React from 'react';
import { withStyles } from 'material-ui/styles';

const styles = {
    main: {
        marginTop: 48,
        padding: 10,
    },
    foo: {
        margin: 0,
    },
};

interface Props {
    message: string;
};

type ClassNames = { classes: { [className in keyof typeof styles]: string } };

class App extends React.Component<Props & ClassNames> {
    render() {
        const { classes, message } = this.props;
        return (
            <div className={classes.main}>
                <div className={classes.foo} >
                    Hello World! {message}
                </div>
            </div>
        );
    }
}

export default withStyles(styles)(App);

مفهوم

عمل الكود بشكل جيد في الإصدار 1.0.0-beta.10 ، عندما قمت بالترقية إلى 1.0.0-beta.12 حصلت على خطأ في النوع.

في مقتطف الشفرة المقدم ، استخدمت خدعة keyof typeof styles حتى لا أحتاج إلى تحديد قائمة بأسماء الفئات مرتين (لا أحب التكرار بشدة). لقد جربت أيضًا أشكالًا أخرى:

type ClassNames = WithStyles<keyof typeof styles>;

والقيام بذلك بالطريقة الأكثر شيوعًا (كما هو موضح في styles.spec.tsx ):

type ComponentClassNames = 'main' | 'foo';
type ClassNames = WithStyles<ComponentClassNames>;

ما زلت أحصل على نفس الخطأ.

يبدو أن تعريف النوع السابق سيعيد مكونًا يكون نوع الدعائم الخاص به هو StyledComponentProps الذي يحتوي على خاصية classes اختيارية. التعريف الجديد ...

<P, C extends React.ComponentClass<P & StyledComponentProps<Names>>>(
    component: C
  ): C;

... إرجاع نفس النوع C مثل المكون ، هذا يعني أن تمرير ClassNames الذي لم يتم وضع علامة عليه ينتشر اختياريًا للمكون المرتجع. أرى مذكورًا هنا استخدام Partial<> والذي أعتقد أنه اختراق قبيح.

بيئتك

| التقنية | الإصدار |
| -------------- | --------- |
| واجهة المستخدم المادية | 1.0.0 بيتا 12 |
| رد فعل | 15.6.1 |
| متصفح | كروم 61.0.3163.100 |

discussion typescript

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

لقد حللت باستخدام إعادة التكوين

مثال

import { StyleRules, Theme, withStyles } from "material-ui/styles";
import * as React from "react";
import { compose } from "recompose";

interface IProps {
    classes?: any; // <-- add question mark
    text: string;
}

const styles = (theme: Theme): StyleRules => ({
    root: {

    },
});

@compose(
    withStyles(styles),
)
export class MyComponent extends React.Component<IProps> {
    render() {
        const { classes, text } = this.props;
        return (
            <div className={classes.root}>
                {text}
            </div>
        );
    }
}

ال 55 كومينتر

cfilipov عند تزيين فئة مكون ، يجب عليك استخدام StyledComponentProps بدلاً من WithStyles ، وإذا كنت في وضع فحص النوع الصارم ، فأنت بحاجة إلى استخدام عامل التأكيد غير الفارغ ! للاستخراج حقول classes . هذا حل وسط للسماح باستخدام withStyles كمصمم فئة. يعاني مصممو الفئة في TypeScript من القيود المفروضة على أن نوع الإرجاع يجب أن يتطابق مع نوع الوسيطة. خيار واحد فقط في ظل هذه القيود ممكن:

  1. لا تدعم استخدام withStyles كمصمم للفصل الدراسي
  2. تتطلب تمرير خاصية وهمية classes عند إنشاء عنصر من نوع المكون المزخرف (الحل الوسط السابق ، والذي كان مزعجًا أكثر )
  3. تتطلب أن يُعتبر classes لاغياً داخل المكون ، مما يجبرك على استخدام عامل التشغيل ! عند الوصول إلى الحقول الخاصة به ( التسوية الحالية )

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

export default withStyles(styles)<Props>(({ classes, message }) => (
  <div className={classes.main}>
    <div className={classes.foo}>
      Hello World! {message}
    </div>
  </div>
));

أرى مذكورًا هنا استخدام Partial <> والذي أعتقد أنه اختراق قبيح.

إذا قرأت متابعي لهذا التعليق ، فسترى أن Partial<> غير مطلوب.

إذا قرأت متابعي لهذا التعليق ، فسترى أن الجزء <> غير مطلوب.

رأيت تعليقك بخصوص Partial<> . يؤدي استخدام StyledComponentProps أساسي إلى نفس الشيء (إنه يستخدم Partial<> في هذا التعريف). وجعتي من ذلك الآن يجب الوصول إلى أسماء الفئات بـ ! (كما ذكرت). أعتقد أن تمرير دمية وهمية classes أو طلب استخدام ! كلاهما تنازلات سيئة.

للتوضيح ، أعتقد أن المشكلة الجذرية التي أواجهها هنا هي اختيار تقديم انحدار إلى المخصص في محاولة للتغلب على قيود ميزة تجريبية للطباعة المطبوعة. أعترف ببعض التحيز لأنني لا أهتم بالمصممون ، في حين أن البعض الآخر يفعل ذلك بوضوح ، لكن المقايضة هنا ليست منطقية بالنسبة لي.

cfilipov كان أول مُصمم لطباعة withStyles هو اختيار الخيار (1) ، أي جعل الكتابة صحيحة تمامًا لكل من مكونات الفئة والوظيفة ، على حساب استخدام withStyles كمصمم فئة . ثم تلقيت ملاحظات مفادها أن استخدام بناء جملة مصمم الديكور كان طلبًا شائعًا ، لذلك قمت بالتبديل إلى الخيار (3). يسعدني إعادة النظر في هذا القرار ؛ أنا أيضًا أفضل أمان الكتابة على دعم الديكور في حالته شبه الوظيفية الحالية.

نعم ، أنا أفهم الرغبة في دعم طلب شعبي مثل هذا. أريد استخدام المصممين أيضًا ، لكنني ما زلت أواجه العديد من المشكلات معهم في كل مرة أفعل فيها (خارج mui) لذلك قررت شخصيًا عدم استخدامها حتى يصبحوا جاهزين.

يبدو أنك تشارك قلقي وليس لدي الكثير لأضيفه ، لذا آمل أن يتمكن الآخرون من تقديم ملاحظات في هذا الاتجاه للمساعدة في التأثير عليه.

لقد تحولت إلى الإصدار التجريبي 13 من الإصدار التجريبي 10 لمعرفة ما إذا كان أي شيء قد تغير ونعم هذه مشكلة حقيقية. لرمي 2 سنتي هنا ، بالنسبة لي ، الديكور تجريبي. من الواضح أنه يمكن تغييرها في المستقبل. وحتى ذلك الحين ، سأدعم تمامًا الطريقة الدقيقة بنسبة 100٪. أنا أفضل أن يكون لدي نوع أمان متماسك لاختراق الأنواع الخاصة بي لجعل الأشياء تعمل.

يبدو 8550 كدليل إضافي على أن الناس مرتبكون بهذا الأمر ، ويجب أن نفكر في عدم دعم @withStyles() كمصمم (في TypeScript).

هذا ما سيبدو عليه "تزيين" الفصل إذا قمنا بتصحيح الكتابة:

type NonStyleProps = {
  text: string
};

const styles = {
  root: {
    backgroundColor: 'red'
  }
};

const DecoratedComponent = withStyles(styles)(
  class extends React.Component<NonStyleProps & WithStyles<'root'>> {
    render() {
      return (
        <div className={this.props.classes.root}>
          {this.props.text}
        </div>
      );
    }
  }
);

pelotom لا يزال يتعين علي المضي قدمًا من الإصدار التجريبي 10 بسبب هذه المشكلة. لقد قدمت تعليقًا حول تصميم الفصل باستخدام طريقة اتصال Redux من قبل. أعتقد أنه سهل نسبيًا وقويًا. في # 8059 التعليق الثالث هو نفسي مع الأنواع.

pelotom شكرا جزيلا withStyles للتخلي عن دعم التزيين الخاص به من أجل الحصول على أمان أفضل من النوع.

يجب ألا ندعمwithStyles () كديكور (في TypeScript).

pelotom أنا شخصياً أؤيد هذا التغيير. sebald ماذا تريد أن تفعل هنا؟

إنه تغيير بسيط. تقدمت وفتحت العلاقات العامة في حال كنت تريد المضي قدمًا بها 🙂

pelotom هل ستظل الكتابة تعمل إذا استخدمتها بهذه الطريقة؟

interface IStyles {
    // styles interface
}
interface IHeaderInfoStyles {
    classes: any;
}
interface IHeaderInfoProps {
    // properties resulting from dispatches
}
interface IHeaderInfoInjectedProps {
   // props injected from parent if any
}
interface IHeaderInfoDispatchProps {
    // dispatches
}
interface IHeaderInfoState {
    // your state for the class
}

type HeaderInfoProps = IHeaderInfoProps & IHeaderInfoInjectedProps & IHeaderInfoDispatchProps & IHeaderInfoStyles;

class HeaderInfo extends Component<HeaderInfoProps, IHeaderInfoState> {

export const HeaderInfo_container = withStyles<IHeaderInfoInjectedProps, IStyles>(styles)(
    connect<IHeaderInfoProps, IHeaderInfoDispatchProps, (IHeaderInfoInjectedProps & IHeaderInfoStyles)>(mapStateToProps, mapDispatchToProps)(HeaderInfo),
);

marcusjwhelan withStyles لم يعد يأخذ معلمتين من النوع ، ولا يجب عليك توفير معلمة نوع للأنماط (يمكن استنتاجها من styles ). يجب أن تكون قادرًا على الكتابة بدلاً من ذلك

withStyles(styles)<NonStyleProps>(...);

إذا أعطيت الأنواع لـ mapStateToProps و mapDispatchToProps فقد أتمكن من أن أوضح لك كيف سيبدو هذا لمثالك.

TL ؛ د. دعونا نجري التغييرات ونرى ما هو رد الفعل العكسي ، على ما أعتقد 👷🏻


oliviertassinaripelotom ¯_ (ツ) _ / ¯ أنا لا أستخدم الديكور ، لذلك شخصيًا ، لا أهتم بهذا التغيير ، لأنني لست متأثرًا. ولكن يبدو أن الكثير من الناس يهتمون بهذه "الميزة". لهذا السبب أضفناها في المقام الأول. هذا هو IMHO ما له الأولوية هنا.

أنا سعيد جدًا بتغييرات withStyles ، لكن عندما تلقي نظرة على مكتبات وظيفية أخرى ، مثل ramda أو recompose ، فإن الكتابة ليست صارمة ، كما أنها ليست آمنة للغاية. في كثير من الأحيان يتعين عليك تمرير عام ، والذي يمثل القيمة المرجعة للدالة. ليست جميلة ولكنها ستعمل مع 99.9٪ من المستخدمين.

لماذا لا يمكننا إعادة النسخ القديمة التي كانت تعمل مع الأشخاص الذين يستخدمون الديكور؟ نظرًا لأنه يحتوي على نوعين من الأدوية الجنيسة ، فقد نتمكن من الحصول على كلا النوعين جنبًا إلى جنب.

أيضًا ، أنا مرتبك قليلاً ما هي قضايا الناس مع الديكور (فيما يتعلق "بعدم العمل"). Libs مثل Angular و https://nestjs.com/ يستخدمونها بكثافة بعد كل شيء. في حالتنا ، يمكن للأشخاص إضافة WithStyles إلى الدعائم وهم بخير.

تضمين التغريدة

لماذا لا يمكننا إعادة النسخ القديمة التي كانت تعمل مع الأشخاص الذين يستخدمون الديكور؟ نظرًا لأنه يحتوي على نوعين من الأدوية الجنيسة ، فقد نتمكن من الحصول على كلا النوعين جنبًا إلى جنب.

لست متأكدًا مما تقصده. لم يكن هناك أي كتابة تسمح للناس باستخدام الزينة دون ألم. عانى التطبيق الأول من # 8267 ، وهو أنه لا يمكنك إنشاء عنصر لمكون مزخرف دون تمرير عنصر وهمي classes prop ، على سبيل المثال <StyledComp classes={{} as any} /> . يعاني التطبيق الثاني (الحالي) من مشكلة عكسية ، وهي أن classes يُنظر إليه على أنه undefined ضمن فئة المكون. إذا كنت تريد استخدام أدوات تزيين TypeScript في شكلها الحالي ، فهذه هي الخيارات الوحيدة المتاحة أمامك ؛ اختر سمك.

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

pelotom نعم ، آسف. أنت على حق. حقا ليس يومي ... 🤐 لذلك دعونا ندمج!

تضمين التغريدة

أيضًا ، أنا مرتبك قليلاً ما هي قضايا الناس مع الديكور (فيما يتعلق "بعدم العمل"). Libs مثل Angular و https://nestjs.com/ يستخدمونها بكثافة بعد كل شيء.

لست متأكدًا من كيفية استخدامها في Angular ، ولكن هناك بالتأكيد حالات استخدام حيث يمكن استخدام الديكور دون ألم ؛ إذا لم يكن مصمم الديكور بحاجة إلى تغيير نوع الفصل الذي يقوم بتزيينه ، فإنهم يعملون بشكل جيد. هذا ليس الوضع الذي لدينا هنا. يحتاج withStyles إلى تغيير نوع المكون الذي يقوم بتزيينه.

pelotom نعم ، بالضبط. إنها مجرد طفرة سيئة. في الواقع ، قد تكون الطريقة التي تنفذ بها TS حاليًا أدوات الديكور مفيدة للمستخدمين Angular ، نظرًا لأن مصممي الديكور AFAIK قاموا بإعداد عقود مع إطار العمل ، مثل "تسجيل هذه الفئة كمكون" أو "إضافة بيانات التعريف حتى أتمكن من استخدامها في DI "... حتى كتابة الله عن هذا يجعلني أشعر

pelotom السبب لديّ الأنواع بالطريقة التي لمكوناتي . لا تتمتع الأنواع حاليًا بأي نوع من الأمان عندما يتعلق الأمر بالمكونات. إن العناصر المحقونة في المثال الخاص بي هي الأنواع التي يتطلبها المكون للعمل. أنواع لتوصيل من react-redux ضرورة أن يكون ذلك من الدعائم التي تأتي من mapStateToProps وDispatchProps التي تأتي من mapDispatchToProps.

في النهاية ، يجب أن تكون هناك قطرات محقونة حتى يعرف المكون الرئيسي لدي أنني بحاجة إلى حقنها وإلا فلن يتم تجميع مشروعي. (هذا ما أريده). هل سيعود هذا التغيير إلى هذا النوع من الأمان؟

marcusjwhelan مرة أخرى ، إذا كان بإمكانك تقديم مثال كامل (ولكن الإصدار التجريبي 10 ، يمكنني أن

pelotom سؤال سخيف ، هل هناك طريقة

wcandillon تابعونا على تويتر.

pelotom قمت بنشر مثال أعلاه ... لماذا تحتاج إلى رؤية أكثر من ذلك؟ يمكنك افتراض أن الخصائص هي أ ، ب ، ج ، د ، هـ. الشيء الوحيد هو أن الدعائم المحقونة يجب أن تنبعث كمتطلب.

يحرر

اكتشفتها.

أنا أشارك في هذه المناقشة متأخرًا بعض الشيء ، لكنني رأيت خطأً مماثلاً كما هو مذكور هنا ، ولم أحدد بعد كيف يمكنني تصحيحه. أنا أستخدم [email protected] و [email protected] .

const LoginForm = withStyles(styles)(
    class extends React.Component<WithStyles<'root' | 'button'>, ILoginFormState> {
    // ...
    }
);

render(
  <MuiThemeProvider theme={theme}>
    <LoginForm />
  </MuiThemeProvider>,
  document.getElementById('login-form')
);

رسالة الخطأ التي أتلقاها في هذه الحالة بالذات هي:

Type '{}' is not assignable to type 'IntrinsicAttributes & WithStyles<"root" | "button"> & StyledComponentP...'.
  Type '{}' is not assignable to type 'WithStyles<"root" | "button" | "progress" | "textField">'.
    Property 'classes' is missing in type '{}'.
 not assignable to type 'WithStyles<"root" | "button" | "progress" | "textField">'.
    Property 'classes' is missing in type '{}'.

عند تزيين فئة مكون ، يجب استخدام StyledComponentProps بدلاً من WithStyles

pelotom - هل يوجد مثال على هذا في مكان ما؟ أواجه الكثير من المشاكل في تحديد كيفية تصميم فئة مكون ذات حالة في TypeScript.

iamjem من الصعب معرفة ذلك نظرًا لأنك لم تقدم styles ، لكن يبدو أن المشكلة الأولى هي أن لديك المزيد من مفاتيح الفصل مذكورة بـ styles مما ذكرته WithStyles<...> . أعتقد إذا قمت بتغييره إلى

const LoginForm = withStyles(styles)(
    class extends React.Component<WithStyles<keyof typeof styles>, ILoginFormState> {
    // ...
    }
);

يجب أن تهتم بالقضية الأولى. ثم يبدو أن هناك مشكلة ثانية ، وهي أن النوع الناتج من LoginForm هو

React.ComponentType<WithStyles<"root" | "button"> & StyledComponentProps<"root" | "button">>

الذي من الواضح أنه غير صحيح ؛ يبدو أن عدم وجود دعامات غير نمطية يربك نظام الكتابة. يمكنك مساعدتها من خلال توضيح ماهية الدعائم غير ذات النمط ، بتمرير {} كوسيطة نوع:

const LoginForm = withStyles(styles)<{}>( // <-- note the type argument
    class extends React.Component<WithStyles<keyof typeof styles>, ILoginFormState> {
    // ...
    }
);

آسف ، الأمر معقد للغاية ، أتمنى لو كنت أعرف طريقة أسهل لجعل هذه الأشياء تعمل!

هذا فعل الحيلة! شكرا لك على المساعدة السريعةpelotom. لقد كنت أستخدم React لفترة طويلة ، لكنني انتقلت مؤخرًا إلى Material-ui ، واعتقدت أنني سأحاول تجربة التنصيب أثناء تواجدي فيه. لا داعي للقول ، أجد أن هناك بعض الحالات المتطورة التي يصعب فيها معرفة كيفية إضفاء السعادة على الطباشير.

لقد حللت باستخدام إعادة التكوين

مثال

import { StyleRules, Theme, withStyles } from "material-ui/styles";
import * as React from "react";
import { compose } from "recompose";

interface IProps {
    classes?: any; // <-- add question mark
    text: string;
}

const styles = (theme: Theme): StyleRules => ({
    root: {

    },
});

@compose(
    withStyles(styles),
)
export class MyComponent extends React.Component<IProps> {
    render() {
        const { classes, text } = this.props;
        return (
            <div className={classes.root}>
                {text}
            </div>
        );
    }
}

كنت أواجه هذه المشكلة (ورقم 8704) ، دون نتيجة واضحة خلال الأيام القليلة الماضية. ثم أخذت النصيحة من pelotom :

يجب عليك استخدام StyledComponentProps بدلاً من WithStyles

وبحثت على GitHub عن طرق مماثلة لحل هذه المشكلة. ولقد وجدت واحدة سبيل المثال العمل 😂. إنها فكرة جيدة ، ومع ذلك ، فقد حل مشكلتي - حاوية منفصلة ومكون مع TypeScript كونها ملف تعريف ارتباط سعيد: المثال المذكور هنا ( ملاحظة: في حالتي ، يكون تعيين المكون في ملف حاوية منفصل ، ولكن الفكرة هي نفس.).

إذا كان أي شخص يعتقد أن هذا حل سيئ ، فأنا منفتح على أي تغييرات وأفكار. RIght now، I'm just glad my code توقف الشكوى.

type Styles = 'foo';
const styles: StyleRulesCallback<Styles> = (theme: Theme) => ({
    foo: {
        position: 'relative',
    }
});

interface Props {
  something: string;
}

class Sidebar extends React.Component<Props & WithStyles<Styles>> {
    render() {
        const { classes, something } = this.props;

        return (
                    <div className={classes.foo}>{something}</div>
        );
    }
}

export default withStyles(styles)<Props>(Sidebar);

لا أرغب في إنشاء مشكلة جديدة ، لكنني جربت أي شيء رأيته في الوثائق ، على سبيل المثال ، وقمت بتمرير المشكلات ، حتى مع إعادة التكوين ، لكن لا يمكنني جعل المكون الخاص بي يعمل عندما أقوم بإضافة بعض الخصائص إليه.
والموارد التي وجدتها هي في الغالب مع إصدارات أقدم من TS أو MUI أو حتى React.

هذا هو المكون الخاص بي:

import React from 'react';
import AppBar from 'material-ui/AppBar';
import { withStyles, WithStyles, StyleRulesCallback } from 'material-ui/styles';

const styles: StyleRulesCallback<'positionFixed'> = () => ({
  positionFixed: {
    top: 'auto',
    bottom: 0,
  },
});

const decorate = withStyles(styles);

interface Props {
   someProp: string;
};

export const BottomNav = decorate<Props>(
  class extends React.Component<Props & WithStyles<'positionFixed'>, {}> {
    render() {
      return (
        <AppBar />
      );
    }
  }
);

export default BottomNav;

والخطأ هو:

TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & Props & StyledComponentProps<"positionFixed"> & { children?: ReactNode; }'.
  Type '{}' is not assignable to type 'Props'.
    Property 'someProp' is missing in type '{}'.

أنا مبتدئ تمامًا في TS ، لكني أجد صفحة التوثيق ، والمثال مربكًا تمامًا و / أو لم يكتمل.

إذا كان لديكم أي فكرة ، شكرا لكم ؛-)

otroboe هل تركت الكود الذي تم بالفعل

<BottomNav />

إذا كان الأمر كذلك ، فالمشكلة هي أنك تحتاج إلى تقديم الخاصية someProp (وهي مطلوبة وفقًا لتعريفك لـ Props ):

<BottomNav someProp="foo" />

عار علي ... عار علي.
كنت أركز بشدة على تكامل TS ، لقد نسيت أن أنظر حولي وأتراجع بعض الخطوات.

شكرا جزيلا pelotom : ابتسم:

otroboe أيضا إزالة تكرار السلسلة ...

type Styles = 'positionFixed';

أتمنى لو كان ذلك أسهل ...

نعم فعلت ذلك أيضًا ، شكرًا: +1:

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

أي دليل لماذا يحدث هذا؟

@ nishmeht7 هل يمكنك نشر مقتطف مستقل؟

pelotom لقد عملت للتو على صنع واحدة ، وهي تعمل بشكل جيد في بيئة وضع الحماية الخاصة بي. أنا أعمل حاليًا على تطبيق كبير وما زلت أستخدم الإصدار 1.2.2 من mui ، في حين أن إصدار وضع الحماية الخاص بي هو الأحدث. لذا فأنا أظن أنه بمجرد ترقية الإصدارات لن أتمكن من إعادة إنتاج خطأي.

لقد اتبعت مثال النموذج الأساسي من https://material-ui.com/demos/selects/ لكن تلقيت شكاوى من أن theme لا يحتوي على root (باستخدام أحدث نسخة مطبوعة ومادة- ui) ، ولم يتم تطبيق أي فئة على العنصر form . حاولت متابعة المناقشة أعلاه ، لكنها تبدو غير حاسمة. وبالفعل كانت قائمة الفئات الموروثة تفتقد إلى اسم الفئة الذي تم إنشاؤه لـ form . إذا أضفت اسم الفصل الذي تم إنشاؤه يدويًا (موجود في الأنماط مع console.log(theme) في عناصر التطوير ، فكل شيء على ما يرام ، لذلك يبدو أن الفصل تم إنشاؤه بشكل صحيح. لم يتم تمريره عبر withStyles إلى form الرغم من أن العنصر

لذا عدت إلى الأنماط في الوقت الحالي حتى يتم فرز هذا:

<form style = {{display:'flex',flexWrap:'wrap'}} autoComplete="off">

HenrikBechmann هل حاولت اتباع توثيق الأنماط للطباعة؟ في الماضي ، كان مفيدًا جدًا بالنسبة لي. https://material-ui.com/guides/typescript/

شكرا @ lookfirst! نظرت (وإن لم تكن أولًا :-)) في هذا المستند ، واستخدمت

export default withStyles({
  root: {
    display: 'flex',
    flexWrap: 'wrap',
  },
})(BaseForm)

(تمرير الكائن بدلاً من الوظيفة)

... والذي تجنب الأخطاء المطبعية ، ومكّن من إدخال الفئة التي تم إنشاؤها.

نأمل أن تساعد النصائح الأخرى هناك في التركيبات الأكثر تعقيدًا.

لقد أكدت أيضًا أن الهيكل الأكثر تعقيدًا للوظيفة styles يعمل (يضخ className إنشاؤه في form ):

import React from 'react'

import { withStyles, createStyles, Theme } from '@material-ui/core/styles'

/*
    patterned after first demo https://material-ui.com/demos/selects/ for 3.03
    use Typsecript fixes from here: https://material-ui.com/guides/typescript/
*/

const styles = (theme:Theme) => createStyles({
  root: {
    display: 'flex',
    flexWrap: 'wrap',
  },
})

class BaseForm extends React.Component<any,any> {

    render() {
        const { classes } = this.props

        return (
            <form className = {classes.root} autoComplete="off">
                {this.props.children}
            </form>
        )
    }
}

export default withStyles(styles)(BaseForm)

تحرير: أشار @ eps1lon إلى أن هذا غير ضروري باستخدام WithStyles !

لقد حققت بعض النجاح باستخدام ReturnType<T> لتوليد ClassKey لي:

import * as React from 'react';

import withStyles, {
  StyledComponentProps, 
  StyleRulesCallback,
} from '@material-ui/core/styles/withStyles';

import { Theme } from '@material-ui/core/styles/createMuiTheme';

const overrideStyles = (theme: Theme) => ({
  root: {
    display: 'flex',
    flexDirection: 'column',
  },
});

type Props = StyledComponentProps<keyof ReturnType<typeof overrideStyles>>;

class MyComponent extends React.PureComponent<Props> {
  render() {
    return <div className={this.props.classes.root}></div>;
  }
}

export default withStyles(overrideStyles as StyleRulesCallback, {withTheme: true})(MyComponent);

باستخدام keyof ReturnType<typeof styleOverrides> كـ StyledComponentProps ClassKey سوف تحصل على المفاتيح من الكائن الذي تم إرجاعه بواسطة overrideStyles ويقيك من الاضطرار إلى الاحتفاظ بقائمة بهذه المفاتيح يدويًا . الخلل الوحيد الذي لاحظته هو خطأ في النوع إذا لم أقم بإلقاء overrideStyles as StyleRulesCallback في المكالمة withStyles . لست متأكدًا بنسبة 100٪ من السبب. أعتقد أنه withStyles لا أفهم ما هو overrideStyles لسبب ما.

لتوضيح هذا النوع المتقن إلى حد ما ، يتحول typeof styleOverrides إلى الوظيفة التي تُرجع كائن النمط. ReturnType<T> سيحصل على كائن النمط نفسه. سيوفر لك keyof المفاتيح من كائن النمط.

chrislambe يجب عليك دليل الطباعة . لن تحتاج إلى استخدام ReturnType وما إلى ذلك ، يجب أن يكون createStyles و WithStyles كافيين كمساعدين.

@ eps1lon أوه مهلا ، رائع جدا! شكرا!

fwiw يعجبني زوج createStyles / withStyles أكثر فأكثر كلما أستخدمها. يروج للتعليمات البرمجية المنظمة ، ويتعامل مع جميع مشكلات التصميم / الكتابة المطبوعة ، وإذا كنت أرغب في إنشاء ملف css شرطي محلي ، فأنا فقط أقوم بإنشاء سمات نمط محلية ، والتي بالطبع لها الأسبقية على الفصول الدراسية.

لطيف - جيد!!

باتباع دليل الطباعة باستخدام @ material-ui / Test does not have required attribute classes على:

import React from 'react'
import { Theme, WithStyles, withStyles, createStyles } from '@material-ui/core/styles'

const styles = (theme: Theme) => createStyles({
  root: {
    color: theme.palette.action.active
  },
})

interface Props extends WithStyles<typeof styles> {
  asd: boolean
}

class TestComponent extends React.Component<Props> {

  render() {
    const { classes } = this.props

    return (
      <div className={classes.root}>
      </div>
    )
  }
}

const Test = withStyles(styles)(TestComponent)

const a = () => <Test asd={true}/>

valoricDe هل حللت مشكلتك؟

TrejGun لقد راجعت للتو. مع مكون وظيفي و @ material-ui / [email protected] ليس لدي هذه المشكلة

أنا لا أفهم حقًا.
متابعة المستندات هنا: https://material-ui.com/guides/typescript/#augmenting -your-props-using-withstyles
يبدو أنه يؤدي فقط إلى مشكلة هذه المشكلة الأصلية. عندما تستخدم المكون في مكان ما ، فإن الكتابة المطبوعة تطببك على _pass_ خاصية الفئات كعنصر أساسي بدلاً من إدراك أنها ستكون _injected_ بواسطة withStyles.

لقد كنت أقرأ هذه المشكلات منذ بضع ساعات الآن ولا أفهمها حقًا. أي مساعدة ستكون لطيفة للغاية في هذه المرحلة.

بخصوص هذا الاقتراح أعلاه

cfilipov عند تزيين فئة مكون ، يجب عليك استخدام StyledComponentProps بدلاً من WithStyles ، وإذا كنت في وضع فحص النوع الصارم ، فأنت بحاجة إلى استخدام عامل التأكيد غير الفارغ ! للاستخراج حقول classes . هذا حل وسط للسماح باستخدام withStyles كمصمم فئة. يعاني مصممو الفئة في TypeScript من القيود المفروضة على أن نوع الإرجاع يجب أن يتطابق مع نوع الوسيطة. خيار واحد فقط في ظل هذه القيود ممكن:

  1. لا تدعم استخدام withStyles كمصمم للفصل الدراسي
  2. تتطلب تمرير خاصية وهمية classes عند إنشاء عنصر من نوع المكون المزخرف (الحل الوسط السابق ، والذي كان مزعجًا أكثر )
  3. تتطلب أن يُعتبر classes لاغياً داخل المكون ، مما يجبرك على استخدام عامل التشغيل ! عند الوصول إلى الحقول الخاصة به ( التسوية الحالية )

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

export default withStyles(styles)<Props>(({ classes, message }) => (
  <div className={classes.main}>
    <div className={classes.foo}>
      Hello World! {message}
    </div>
  </div>
));

كيف يمكنني معرفة كيفية استخدام StyledComponentProps ؟ يبدو أنني مجرد تمرير سلاسل المفاتيح المحددة في كائن الأنماط.

لكن المستندات تخبرنا أن نفعل شيئًا لا يعمل ببساطة؟ ماذا ينقصني؟ أود استخدام https://material-ui.com/guides/typescript/#augmenting -your-props-using-withstyles ...

هل هذا ممكن؟

valoricDe ، كيف فعلت المكون الوظيفي الذي لم يكن به هذه المشكلة

TrejGun لقد راجعت للتو. مع مكون وظيفي و @ material-ui / [email protected] ليس لدي هذه المشكلة

أحاول شيئًا كهذا:

`` استيراد رد فعل ، {ChangeEvent، Component، Dispatch} من رد فعل "؛
استيراد PropTypes من "أنواع العناصر" ؛
استيراد {connect} من "رد فعل إعادة" ؛
استيراد {Grid، FormControlLabel، Theme، createStyles، withStyles، Radio، WithStyles} من "@ material-ui / core"؛
استيراد المبلغ من "./Amount" ؛
استيراد {onPastDueFormFieldChange} من "../../store/actions/selectPaymentAmountActions" ؛

أنماط const = (السمة: السمة) =>
createStyles ({
كمية: {
alignSelf: "مركز" ،
} ،
}) ؛

واجهة OwnProps تمتد ويذ ستايلز{}

واجهة StateProps {
الماضي: رقم؛
pastDueOrTotalOrOther: string؛
}

واجهة DispatchProps {
onPastDueFormFieldChange: OnPastDueFormFieldChange ؛
}

اكتب الدعائم = StateProps & DispatchProps & OwnProps ؛

const PastDueFormField = withStyles (الأنماط) (
({class، pastDue، pastDueOrTotalOrOther، onPastDueFormFieldChange}: الدعائم) => (
القيمة = "pastDue"
محدد = {pastDueOrTotalOrOther === "pastDue"}
onChange = {onPastDueFormFieldChange}
التسمية = "تجاوز تاريخ الاستحقاق:"
السيطرة = { }
/>




) ،
) ؛

const mapStateToProps = (الحالة: RootState): StateProps => ({
pastDue: state.customerData.balanceDue.pastDue ،
pastDueOrTotalOrOther: state.customerPaymentsForm.pastDueTotalOrOther ،
}) ؛

تصدير الاتصال الافتراضي(
mapStateToProps ،
{onPastDueFormFieldChange} ،
) (PastDueFormField) ؛

When I use this component I have this error:
```import PastDueFormField
Property 'classes' is missing in type '{}' but required in type 'Readonly<PropsWithChildren<Pick<Pick<Props, "pastDue" | "pastDueOrTotalOrOther" | "onPastDueFormFieldChange"> & StyledComponentProps<"amount">, "classes" | "innerRef"> & OwnProps>>'

yehudamakarov جرب الشفرة بدون react-redux أولاً وأضف connect عندما يعمل كل شيء كما هو متوقع. من الصعب للغاية الحصول على نظرة عامة جيدة عند حقن ما هو الدعامة.

عندما واجهت هذه القضايا سوف

  1. اكتب دعائم المكون الخاصة بي أولاً
  2. تحقق مما إذا كان كل شيء مطلوبًا كما هو متوقع ، أي احصل على missing props
  3. تطبيق خاص
  4. معرفة ما إذا كان الخط المطبوع عليه قد تعرّف على كل دعامة محقونة
  5. كرر 3 حتى يتم تطبيق جميع الحواجز.

يعزز كود أنظف. خاصة فيما يتعلق بترتيب العمليات. أنت حاليًا تخلط بين withStyles و connect بدون فصل المخاوف.

شكرا جزيلا سيباستيان.
لقد قمت بحل مشكلتي ببساطة من خلال عدم تمرير الحجج العامة للتواصل. لقد أخرجت القطعة <StateProps ...> .

أعتقد أن هذه الحجج العامة كانت تعبث بواجهة OwnProps التي تمتد بـ WithStyles <>.

نظرًا لأنني أقوم بتمرير كل شيء إلى المكون على أي حال ، فإن فحص النوع الذي أحصل عليه من Props الخاص بي كافٍ. لست متأكدًا من سبب الحاجة إلى معرف الاتصال بالأدوية <>.

شكرا!

هذا ما سيبدو عليه "تزيين" الفصل إذا قمنا بتصحيح الكتابة:

type NonStyleProps = {
  text: string
};

const styles = {
  root: {
    backgroundColor: 'red'
  }
};

const DecoratedComponent = withStyles(styles)(
  class extends React.Component<NonStyleProps & WithStyles<'root'>> {
    render() {
      return (
        <div className={this.props.classes.root}>
          {this.props.text}
        </div>
      );
    }
  }
);

وكيفية إضافة السمات (useTheme ()) بالداخل مثل:

const decorate = withStyles((theme: Theme) => ({
  root: {
    display: "flex"
  },
  appBar: {
    zIndex: theme.zIndex.drawer + 1,
    transition: theme.transitions.create(["width", "margin"], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.leavingScreen
    })
  }
})
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات