Typescript: Jenis elemen JSX tidak memiliki konstruksi atau panggilan tanda tangan di v3.2.0-rc

Dibuat pada 21 Nov 2018  ·  27Komentar  ·  Sumber: microsoft/TypeScript

Versi TypeScript: 3.2.0-rc, 3.2.1

Kode

import * as React from "react";
import { Component, ReactType} from "react";
function App(props:{component:ReactType}) {
  const Comp: ReactType = props.component
  return (<Comp />)
}

Perilaku yang diharapkan:
Harus menghasilkan keluaran normal sebagai TypeScript 3.1.6

Perilaku sebenarnya:
TS2604: JSX element type 'Comp' does not have any construct or call signatures.

Bug JSTSX Duplicate

Komentar yang paling membantu

bagi saya solusinya adalah:

export type WrapperProps = {
    mainApp: React.ElementType
}

Semua 27 komentar

Ini menghilangkan sisa pesan kesalahan tetapi, untuk memastikan, pastikan Anda menggunakan versi terbaru @types/react dan tidak ada duplikatnya yang tertinggal di node_modules atau file kunci Anda.

EDIT: Anda mungkin bermaksud menggunakan ComponentType dan bukan ReactType

@Bayu_joo

Saya telah memastikan menggunakan @types/react 16.7.7 dan tidak ada duplikat @types/react di yarn.lock .
Jika masalah terjadi karena duplikasi @types/react , itu akan mengembalikan kesalahan Duplication of definition ... .

Saya kembali ke "typescript": "^3.1.6" lalu berfungsi normal.

Ketikan 3.2.1

contoh lainnya


interface P1 {
  p?: boolean
  c?: string
}

interface P2 {
  p?: boolean
  c?: any // if you replace c with string, error goes away
  d?: any
}

declare var C: React.ComponentType<P1> | React.ComponentType<P2>


const a = <C p={true} /> // element does not have any ...

Sepertinya, masalah ini terkait dengan perubahan "diskriminan nullable" baru. Sepertinya ts tidak dapat menemukan antarmuka umum untuk jenis tersebut.
Contoh lainnya

interface P1 {
  p?: any
  c?: string // remove this and it's ok
}

interface P2 {
  p?: boolean
}

Kami memiliki masalah serupa, contoh singkat:

import * as React from 'react'

//
// Types
//

interface Config<P> {
  ElementType: React.ReactType<P>
}

interface EmptyProps {
}

interface Props {
  a?: string
}

type HProps = {
  configEmpty: Config<EmptyProps>,
  config: Config<Props>
}

//
// Component
//

const H: React.FC<HProps> = ({ config, configEmpty }) => {
  const A: React.ReactType<EmptyProps> = configEmpty.ElementType // assigned
  const B: React.ReactType<EmptyProps> = 'div' // assigned

  const C: React.ReactType<Props> = config.ElementType // assigned
  const D: React.ReactType<Props> = 'div' // in this case assignment failed

  return (
    <div>
      <A/> {/* TS2604: JSX element type 'A' does not have any construct or call signatures. */}
      <B/>

      <C/>
      <D/>
    </div>
  )
}

export default H

Saya melihat perilaku ini sama sekali tidak valid, karena A dan B memiliki tipe yang sama . Pada saat yang sama, B dan D memiliki _type serupa_, tetapi D tidak dapat dialihkan 🤔

Kode dalam repo: https://github.com/layershifter/ts-issue

Mereka tidak melakukannya, karena Anda menggunakan const . Jenis A adalah typeof configEmpty.ElementType , tetapi jenis B adalah 'div' . Menggunakan let s akan menunjukkan perilaku yang sama pada keduanya.

@Kovens bagaimana dengan A dan C ? Mengapa C berfungsi sementara A gagal dengan kesalahan does not have any construct ?

Itu karena saya meningkatkan tipe ReactType untuk mengecualikan komponen yang tidak dapat menerima props yang Anda berikan. Karena tidak ada elemen DOM yang dapat menerima { a: string | undefined } , mereka semua dikecualikan, dan hanya komponen fungsi / kelas yang masih diperbolehkan untuk ditugaskan padanya.

@Kovens, terima kasih 👍 Sekarang masalah dengan penugasan jelas bagi saya, tapi bagaimana dengan ini?

import * as React from 'react'

//
// Types
//

interface Config<P> {
  ElementType: React.ReactType<P>
}

interface Empty {}
interface Props { a?: string }

type HProps = {
  configEmpty: Config<Empty>,
  config: Config<Props>
}

//
// Component
//

const H: React.FC<HProps> = ({ config, configEmpty }) => {
  const A: React.ReactType<Empty> = configEmpty.ElementType // is React.ReactType<Empty>
  const B: React.ReactType<Empty> = 'div' // is string
  const C: React.ReactType<Props> = config.ElementType // is React.ReactType<Props>

  return (
    <div>
      {/* React.ReactType<Empty> */} <A/> {/* <--- TS2604: JSX element type 'A' does not have any construct or call signatures. */}
      {/* React.ReactType<Empty> */} <B/>
      {/* React.ReactType<Props> */} <C/>
    </div>
  )
}

export default H

A dan B memiliki tipe yang didefinisikan dengan jelas, mengapa A gagal? Benar-benar hal yang membingungkan.

Saya mungkin akan mengatakan kesalahan @rexpan dan @goloveychuk mirip dengan # 28795 dan # 28768 berdasarkan konstruktor JSX bersyarat.

Hm, jadi masalahnya adalah bahwa ReactType<any> mengembalikan gabungan _every builtin jsx tag_ (ditambah ComponentType<any> , tapi bagian itu tidak bermasalah), dan tanda tangan untuk komponen tersebut tidak menyederhanakan (ada bukan tanda tangan yang dengan sempurna mencakup semua yang lain). Ini juga bergantung pada # 7294 untuk diperbaiki. Sisi positifnya, perubahan mendasar yang diperlukan untuk memperbaiki semua masalah JSX yang dilaporkan ini adalah sama.

Untuk konteks, kami secara efektif membuat tipe seperti ini:

declare const JsxSigs: {[K in keyof JSX.IntrinsicElements]: ((props: JSX.IntrinsicElements[K]) => JSX.Element)}[keyof JSX.IntrinsicElements];

yang akhirnya menjadi penyatuan banyak tanda tangan unik.

Sebelum saya mengubahnya menjadi gabungan dari semua tag jsx bawaan, itu adalah _just_ string | ComponentType<any> , yang bahkan lebih buruk.

Ya, terutama karena sebelum 3.2, string ketik tag hanya dengan diam-diam _disabled_ typechecker, karena kesalahan "indeks tidak ditemukan" yang seharusnya tidak terjadi tidak pernah terjadi.

Masalah ini telah ditandai sebagai duplikat dan tidak ada aktivitas apa pun dalam sehari terakhir. Itu telah ditutup untuk keperluan pemeliharaan rumah otomatis.

Mengalami masalah yang mungkin terkait. Saya memiliki komponen berikut:

function MaybeLabel(props: { useLabel: boolean }) {
   const { useLabel } = props;
   const TagName = useLabel ? 'label' : 'div';

   return <TagName>Woookie</TagName>
}

yang mengakibatkan

error TS2604: JSX element type 'TagName' does bukan have any construct or call signatures.

sementara

function MaybeLabel2(props: { useLabel: boolean }) {
   const { useLabel } = props;
   const TagName = useLabel ? 'span' : 'div';

   return <TagName>Woookie</TagName>
}

sepenuhnya dapat diterima oleh penyusun skrip ketikan. Dengan adanya:

export function MaybeLabel3(props: { useLabel: boolean }) {
    const { useLabel } = props;
    const TagName = useLabel ? 'label' : 'div';

    return React.createElement(TagName, 'Wookie')
}

Di mana satu-satunya perbedaan dalam MaybeLabel2 adalah bahwa saya menggunakan span daripada label (menggunakan span bukan div juga tampaknya dapat diterima ). MaybeLabel3 membuatnya lebih aneh, karena seharusnya itulah yang dikompilasi MaybeLabel .

Menggunakan versi terbaru @ types / react dan @ types / react-dom, dan memverifikasi masalah di skrip ketikan 3.2.1, 3.2.2, dan 3.3.0-dev.20181219. Di 3.1.6 semuanya berfungsi seperti yang diharapkan (tidak ada contoh yang menghasilkan kesalahan)

bagi saya solusinya adalah:

export type WrapperProps = {
    mainApp: React.ElementType
}

@ TacBS tolong

Saya mungkin telah salah memahami utasnya, tetapi saya ingin meneruskan referensi ke Elemen jsx ke elemen jsx lain:

export const AppWrapper = hot(module)((props: WrapperProps) => {

    const MainApp = props.mainApp;
    if (!MainApp)  // <-- JSX elements MUST start with upper case!!
        throw new ImplementationMissingException("mainApp was not specified!!");

    return (
        <Router history={BrowserHistoryModule.getHistory()}>
            <MainApp prop1={"value"}/>
        </Router>)
});

Bersama dengan:

export type WrapperProps = {
    mainApp: React.ElementType<{prop1:string}>
}

@ TacB0sS Bagi saya trik utama adalah menambahkan kondisi if . Sepertinya tidak masalah apakah Anda menggunakan React.ComponentType atau React.ElementType

Saya tidak yakin saya memahami hasil dari ini. Saya memiliki kesalahan serupa yang belum dapat saya atasi. Ini kasus penggunaan saya:

// Logo.tsx

import classNames from 'classnames';

interface Props extends React.HTMLAttributes<HTMLElement> {
  tag?: React.ReactType;
}

const Logo: React.SFC<Props> = props => {
  const { tag: Tag = 'div', className, ...rest } = props;
  return (
    <Tag
      className={classNames(styles.logo, className)}
      {...rest}
      dangerouslySetInnerHTML={{ __html: logo }}
    />
  );
};

dan kemudian saya menggunakannya seperti di komponen lain seperti:

const Header: React.SFC<{}> = () => {
  return (
    <div>
      <Logo tag="h1" aria-label="Syn By Design: Eric Masiello's Portfolio" />
      Header online
    </div>
  );
};

Ketika saya menjalankan kompiler, saya mendapatkan kesalahan ini:

components/Logo.tsx:13:6 - error TS2604: JSX element type 'Tag' does not have any construct or call signatures.

13     <Tag
        ~~~


Found 1 error.

Ada ide bagaimana membuat ini bekerja?

Alih-alih Component , gunakan ComponentClass

Saya mendapat kesalahan ini karena saya mengimpor default tetapi menyatakan ekspor yang sesuai sebagai bernama alih-alih default di file .d.ts ... membingungkan saya untuk sementara

Hanya ingin menambahkan ini di sini. Tidak yakin apakah ini sudah dikatakan tetapi jika Anda melakukan komponen urutan hirer Anda ingin menggunakan tipe React.ComponentType

. " https://flow.org/en/docs/react/types/#toc -react-componenttype"

@ericmasiello Saya akhirnya menggunakan React.ElementType untuk komponen yang diteruskan secara dinamis. Kasus penggunaan saya pada dasarnya adalah sebagai berikut:

type Props = {
    heading: React.ElementType
}
const Header: FC<Props> = props => {
    const Header = props.heading ?? 'h2';
    return (
        <Header className="some-class"><children /></Header>
    )
}

@ericmasiello Saya akhirnya menggunakan React.ElementType untuk komponen yang diteruskan secara dinamis. Kasus penggunaan saya pada dasarnya adalah sebagai berikut:


type Props = {

    heading: React.ElementType

}

const Header: FC<Props> = props => {

    const Header = props.heading ?? 'h2';

    return (

        <Header className="some-class"><children /></Header>

    )

}

Keren! Versi Typecript apa dan versi @ types / react apa yang telah Anda instal?

@rumahsakitotak

Keren! Versi Typecript apa dan versi @ types / react apa yang telah Anda instal?

[email protected]
@ types / [email protected]

Saya memecahkan masalah ini dengan melakukan salah satu dari dua hal ini:

Kasus 1:

file .d.ts:

declare module "foo" {
   interface PropFoo {
      propy: string;
   }

   class MyTypedComponent extends React.Component<PropFoo> { }
}

Reaksi:

import MyTypedComponent from "foo";

function AnotherComponent() {

   /* Notice in here we have to use the dot operator and reference the component */
   return <MyTypedComponent.MyTypedComponent /> 
}

Perhatikan bahwa, untuk menggunakan komponen yang baru diketik, kita harus menulis _MyTypedComponent.MyTypedComponent_. Ini mungkin jelas bagi sebagian orang, tetapi saya menyia-nyiakan banyak waktu ketika yang harus saya lakukan hanyalah menggunakan operator titik untuk mengimpor dan mereferensikan komponen.

Kasus 2 [hanyalah cara lain untuk menulis Kasus 1]:

file .d.ts:

declare module "foo" {
   interface PropFoo {
      propy: string;
   }

   export default class MyTypedComponent extends React.Component<PropFoo> { } //Notice the export default in here
}

Reaksi:

import MyTypedComponent from "foo";

function AnotherComponent() {

   /* Since this component is default exported, no need to use the dot operator */
   return <MyTypedComponent /> 
}

Jadi, pada dasarnya, periksa ekspor Anda, ekspor default, dan impor Anda dan pastikan Anda merujuk dengan benar.

Saya sangat menyesal atas bahasa Inggris saya dan saya harap ini membantu.

bagi saya solusinya adalah:

export type WrapperProps = {
  mainApp: React.ElementType
}

niu b

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

weswigham picture weswigham  ·  3Komentar

wmaurer picture wmaurer  ·  3Komentar

manekinekko picture manekinekko  ·  3Komentar

blendsdk picture blendsdk  ·  3Komentar

bgrieder picture bgrieder  ·  3Komentar