Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

my pipeline is breaking due to a Typescript error:...

12

what version of payload are you on?

  • default discord avatar
    jamesryandevlast year
    "payload": "^1.11.4",
  • interesting, works for me



    want to share your users collection here again?

  • default discord avatar
    jamesryandevlast year
    import { CollectionConfig } from 'payload/types';
    
    
    
    const Users: CollectionConfig = {
        slug: 'users',
        admin: {
            useAsTitle: 'email',
            disableDuplicate: true,
        },
        fields: [
          
            {
                label: 'Password history',
                name: 'passwordHistory',
                type: 'array',
                admin: {
                    initCollapsed: true,
                    components: {
                        RowLabel: RowLabel,
                    },
                    condition: (_, siblingData) => {
                        return siblingData.passwordHistory && siblingData.passwordHistory.length > 0;
                    },
                },
                access: {
                    create: () => false,
                    update: () => false,
                    read: userHasUserManagerRole,
                },
    
                fields: [
                    {
                        name: 'password',
                        type: 'text',
                        label: 'Password',
                        hidden: true,
                    },
                    {
                        name: 'updatedAt',
                        type: 'text',
                        label: 'Updated at',
                        hidden: true,
                    },
                    {
                        name: 'updatedBy',
                        type: 'text',
                        label: 'Updated by',
                        hidden: true,
                    },
                    {
                        name: 'userSnapshot',
                        type: 'textarea',
                        label: 'User snapshot',
                        hidden: true,
                    },
                ],
            },
        ],
        hooks: {
            beforeOperation: [checkPasswordStrength],
            beforeValidate: [storePasswordHistory],
        },
    };
    
    export default Users;


    RowLabel:



    `
    const RowLabel: React.FC<{ data: any, index: number }> = ({ data, index }) => {
      const checkIsCompactView = width => (width <= 1572 && width >= 1024) || width <= 690;
        const [isCompactView, setIsCompactView] = useState(checkIsCompactView(window.innerWidth));
    
        useEffect(() => {
            const handleResize = () => {
                setIsCompactView(checkIsCompactView(window.innerWidth));
            };
    
            window.addEventListener('resize', handleResize);
            return () => {
                window.removeEventListener('resize', handleResize);
            };
        }, []);
    
        if (isCompactView) {
            return (
                <CompactRowLabelWrapper>
                    <EditLabel>Edited:</EditLabel>
                    <CompactP>
                        {data.updatedAt} by {data.updatedBy}
                    </CompactP>
                </CompactRowLabelWrapper>
            );
        } else {
            return (
                <RowLabelWrapper>
                    <Index>
                        <P>Index:</P>
                        <DataItem>{index}</DataItem>
                    </Index>
                    <UpdatedOn>
                        <P>Updated on:</P>
                        <DataItem>{data.updatedAt}</DataItem>
                    </UpdatedOn>
                    <UpdatedBy>
                        <P>Updated by:</P>
                        <DataItem>{data.updatedBy}</DataItem>
                    </UpdatedBy>
                </RowLabelWrapper>
            );
        }
    };


    Even using the supplied

    RowLabel

    example in the docs - the TS error would flag up as well so I don't think it's to do w/ my custom component

  • The one in the docs should show how to import

    RowLabelArgs

    but does not. Here is how you should type your custom component:



    import { RowLabelArgs } from 'payload/dist/admin/components/forms/RowLabel/types';
    import * as React from 'react';
    
    
    export const RowLabelComponent: React.FC<RowLabelArgs> = ({ data, index }) => (
      <div>custom row label</div>
    );


    We should make the import better for the row label args and update the docs.



    But I still was unable to repro the error message you are getting. Maybe try removing your yarn lock and node modules and re-run

    yarn
  • default discord avatar
    jamesryandevlast year

    Thanks

    @281120856527077378

    - spinning a fresh deployment 🤞



    I'll action your recommendations as well re

    yarn.lock
  • default discord avatar
    tais.mlast year
    @281120856527077378

    I'm getting TS error in the same place as well, no matter how I type my custom RowLabel component. I currently have the exact same type you suggested:



    import { RowLabelArgs } from "payload/dist/admin/components/forms/RowLabel/types";
    
    const AnswerRowLabel: React.FC<RowLabelArgs> = ({ data, index }) => {


    which returns either the default string or a custom React component.



    I've already removed my node_modules and reinstalled the dependencies, but still get the following error when I try to build (no error on VSCode though):


    src/admin/components/AnswerRowLabel.tsx:14:7 - error TS2322: Type '({ data, index }: RowLabelArgs) => string | Element' is not assignable to type 'FC<RowLabelArgs>'.
      Type 'string | Element' is not assignable to type 'ReactElement<any, any>'.
        Type 'string' is not assignable to type 'ReactElement<any, any>'.


    am I missing something? :/



    (I'm on Payload 1.15.6)

  • I think you can just wrap your string label in a fragment, i.e.

    return <>{label}</>
  • default discord avatar
    tais.mlast year

    but when I return a string I don't get any errors, only when I return JSX.

  • You mean, when using a function and returning a string right?



    is a string a valid return type from a React component?

  • default discord avatar
    tais.mlast year

    this is what I had for the

    RowLabel

    component:


    function AnswerRowLabel({ data, index }: RowLabelArgs) {
      if (!data?.answerText) {
        return `Answer ${index}`;
      }
    
      const status = data.isCorrect ? "✅" : "🚫";
    
      return (
        <div style={{ display: "flex", gap: "8px", alignItems: "center" }}>
          <span>{status}</span> <span>{data.answerText}</span>
        </div>
      );
    }

    but I had to change the second return to just a regular string

    ${status} ${data.answerText}

    to avoid the TS error on build.

  • You could make it this instead:


    function AnswerRowLabel({ data, index }: RowLabelArgs) {
      if (!data?.answerText) {
        return <React.Fragment>Answer {index}</React.Fragment>;
      }
    
      const status = data.isCorrect ? "✅" : "🚫";
    
      return (
        <div style={{ display: "flex", gap: "8px", alignItems: "center" }}>
          <span>{status}</span> <span>{data.answerText}</span>
        </div>
      );
    }
  • default discord avatar
    tais.mlast year

    a-ha, that works. but string is a valid

    ReactNode

    , so I wouldn't expect to have to add a fragment around it. 🤔



    export type RowLabelFunction = (args: RowLabelArgs) => string;
    export type RowLabelComponent = React.ComponentType<RowLabelArgs>;

    maybe these types could be combined into one:


    export type RowLabelComponent = (args: RowLabelArgs) => React.ReactNode;
Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.