IT이야기

'정의되지 않음'.ts(2722)일 수 있는 개체를 호출할 수 없음

cyworld 2022. 3. 7. 21:33
반응형

'정의되지 않음'.ts(2722)일 수 있는 개체를 호출할 수 없음

단추 구성요소가 있어.나는 그냥 한 가지만 건네준다.onClick내가 정의한 많은 선택적 소품 중에서 소품:

const Button = (props: ButtonProps) => {
    const handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
        props.onClick(e);
    }
    return (
        <StyledButton onClick={handleClick}>
            {props.children}
        </StyledButton>
    );
};

그럼 이렇게 쓰고 있어.

<Button onClick={(e) => {
    console.log(e);
}}>Click me!</Button>

이제 어떻게 물체가 정의되지 않을 수 있는가?나는 형식 정의에 따라 그것과 저것에게도 그 기능을 분명히 전달하고 있다.그래서, 나는 어떤 대상을 그것에 넘기고 있다.간단해!

...
onClick?: React.MouseEventHandler<HTMLElement>
...

최근 이 프로젝트에서 몇 가지 더 엄격한 검사를 추가했는데 관련 사항은 다음과 같다.

"strictFunctionTypes": true,
"strictNullChecks": true

strict:true이미 존재하는 동안, 이 오류는 발생하지 않았다.

여기서 뭐가 문제야?

업데이트 - 추가된 유형

export interface IBaseButtonProps {
    type?: ButtonType;
    disabled?: boolean;
    size?: ButtonSize;
    block?: boolean;
    loading?: boolean | { delay?: number };
    icon?: string;
    className?: string;
    prefixCls?: string;
    children?: React.ReactNode;
}

export type AnchorButtonProps = {
    href: string,
    target?: string,
    onClick: React.MouseEventHandler<HTMLElement>
} & IBaseButtonProps & Omit<React.AnchorHTMLAttributes<any>, 'type' | 'onClick'>;


export type NativeButtonProps = {
    onClick: React.MouseEventHandler<HTMLElement>,
    htmlType?: ButtonHTMLType
} & IBaseButtonProps & Omit<React.ButtonHTMLAttributes<any>, 'type' | 'onClick'>;

export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>

주의:

가능한 해결책은 소품을 해체하고 기본 소품을 추가하는 것이다.또는 사용defaultProps반응에서.하지만 내가 정말로 그것을 Typecript와 함께 요구해야 하는지는 확실하지 않다.

이제 어떻게 물체가 정의되지 않을 수 있을까?[sic]

의 사용Partial<T>주위에서export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>원인들onClick선택적이다사용할 때Partial<T>, 모든 속성 수신:?그래서 선택권이 되는 거지 모든 게 정의되지 않을 수 있다는 뜻이지

두 가지 해결책이 있다: 하나는 지키는 것이다.ButtonProps와 같은onClick선택 사항으로서, 그리고 그것을 확인하기 위해.onClick호출하기 전에 정의된다(수정 1) 다른 하나는 변경해야 함ButtonProps만들기 위해서onClick필수(2 및 3)

수정 1:onClick선택 사항으로 남아 있다

사용ButtonProps이미 가지고 있는 것을 확인한 다음onClick부르기 전에 정의된다.네가 코멘트에 링크한 코드에서 antd는 이렇게 해.

const Button = (props: ButtonProps) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    if (props.onClick) props.onClick(e); // works
  };
};

수정 2:onClick필수가 되다

변화하다ButtonProps을 적용하지 않음으로써Partial에게NativeButtonProps:

type ButtonProps1 = Partial<AnchorButtonProps> & NativeButtonProps;

const Button1 = (props: ButtonProps1) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    props.onClick(e); // works
  };
};

수정 3:onClick역시 필요하게 되다.

정의 aRequireKeys선택 사항이 아닌 키를 지정할 수 있는 유형.

type RequireKeys<T, TNames extends keyof T> = T &
  { [P in keyof T]-?: P extends TNames ? T[P] : never };

type ButtonProps2 = RequireKeys<ButtonProps, "onClick">;

const Button2 = (props: ButtonProps2) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    props.onClick(e); // works
  };
};

매핑된 유형에 대한 답변: 선택적 수정자를 제거하면 내가 정의한 방법에 대한 자세한 정보가 있음RequireKeys<T>.

Typecript 3.7+에서는 선택적 체인을 사용하여 선택적 프로펠러 방법을 호출할 수도 있다.

const Button = (props: ButtonProps) => {
  const handleClick: React.MouseEventHandler<
    HTMLButtonElement | HTMLAnchorElement
  > = e => {
    props.onClick?.(e); // works
  };
};

체인 사용에 대한 자세한 내용은 https://www.stefanjudis.com/today-i-learned/optional-chaining-helps-to-avoid-undefined-is-not-a-function-exceptions/을 참조하십시오.

그냥 명료한 대답.

if (props.onClick) props.onClick(e);

함수 소품을 정의하는 경우 선택 사항으로 정의하십시오.

export type ButtonProps = {
  function?: () => void;
};

설명:기능을 소품으로 사용하고자 할 경우 그 기능(소품)을 전달하고자 하는 경우가 있을 수 있고, 그 기능(소품)을 전달하고 싶지 않은 경우도 있을 수 있다.

예를 들어,

Code 를 호출한다.<Home/>구성 요소, say index.ts/index.js

function myfunction(){
  //do something
  alert("hello")
}

return (
  <>
     <Home myfunction={myfunction}/>    //passing prop
     <Home/>                            // not passing
  </>
)

JS에서는 home.js.

export default function Home({myfunction}) {
  const const1 = "Hello World"
  return (
    //do something
    myfunction();      //IMPORTANT line
  )
}

현재, 그것은 TS, home.ts와 거의 동등하다.

TS에서는 모든 것의 종류를 정의한다.그래서 그 경우에는 이 기능의 유형을 정의해야 한다.myfunction그리고 우리가 지나가고 있다는 것도.

그래서, 이 기능을 위해, 우리는,

  • 파람을 받지 않기 때문에()(중간 괄호)면 충분해, 만약 거기에 어떤 매개 변수가 있다면, 우리는 그것들에 대한 유형도 정의해야 해.
  • 아무 것도 반환하지 않으므로 반환 유형void
export type HomeProps = {
  myfunction?: () => void;
};

export default function Home({ myfunction }: HomeProps) {
  const const1 = "Hello World"
  return (
    //do something
    if (myfunction) myfunction();      //IMPORTANT line
  )
}

힌트: 위 답변

 (props.onClick && props.onClick(e));

가장 좋은 변종은 사용하는 것이다.?.call(this: unknown, ...args: any[])또는?.apply(this: unknown, args: any[])방법들

자, 다음 선언이 있다고 상상해 봅시다.

type callback = ((x: number, y: number) => number) | null;

let a: callback;
let b: callback;

a = (x, y) => x + y;   // it works with arrow functions
b = function (x, y) {  // and normal functions
  return x + y;
};

function x(cb1: callback, cb2: callback) {
  console.log(cb1?.call(0, 5, 6));     // in this case you
  console.log(cb2?.call(0, 5, 6));     // cant invoke cb1() or cb2()
  console.log(cb1?.apply(0, [5, 6]));  // but you can use call or apply
  console.log(cb2?.apply(0, [5, 6]));  // where first parameter can be any value
}

x(a, b); // 11 11 11 11

class C {
  public f?: callback;
  public setF() {
    this.f = (x, y) => {
      return x + y;
    };
  }
}
const c = new C(); // same with objects
c.setF();
console.log(c?.f?.call(c, 2, 3)); // 5

다음에 오는 사람은 누구라도.또 다른 옵션은 유형 주물을 사용하는 것이다.다음과 같다:

props = props as NativeProps

내 경험상 나는 부분 타입의 객체를 반환하는 컨텍스트를 사용했고, 정의되지 않은 오류를 극복하기 위해 타입 캐스팅을 해야 했다.다음과 같다:

const {setSomething} = useContext(SomePartialContext) as MyContextType

이것은 나에게 이 문제를 해결하는데 도움을 준 구문이다.

솔루션을 얻는 다양한 방법:

search.prop('onSearch')!('text' as unknown)
search.prop('onSearch')!({} as unknown)
search.prop('onSearch')!({} as any)

주요 내용은 다음과 같다.!({} as any}

참조URL: https://stackoverflow.com/questions/56913963/cannot-invoke-an-object-which-is-possibly-undefined-ts2722

반응형