React-native: Javascript'ten Typescript'e Geçiş


Proje kod tabanımızı JavaScript'ten TypeScript'e taşımak için maliyeti değerlendirmeye çalışıyorum ve ana hedefimiz şu anda tüm kod tabanımızı TypeScript'e dönüştürmek zorunda kalmamak, bunu adım adım yapabilmek.

Bunun için dokümanı takip ettim https://reactnative.dev/docs/typescript

Rastgele bir dosyayı TypeScript'e dönüştürmeyi denedim

interface Props {
  iconName: string;
  iconType?: string;
  text: string;
  onPress?(evt: GestureResponderEvent): void;
  style?: any;
}

const ButtonWithBigIconAndSmallText: FC<Props> = ({
  iconName, iconType, text, onPress, style,
}): ReactElement => (
  <TouchableOpacity onPress={onPress} style={{ ...styles.button, ...style }}>
    {/* Commented it to reduce the error scope */}
    {/*<HinfactIcon name={iconName} type={iconType} size={40} />*/}
    <HinfactText style={{
      textTransform: 'uppercase',
      fontSize: 9,
      fontWeight: 'bold',
    }}
    >
      {text}
    </HinfactText>
  </TouchableOpacity>
);

bu hatalarla sonuçlanan

error TS2786: 'HinfactText' cannot be used as a JSX component. Its instance type 'HinfactText' is not a valid JSX element.
error TS2607:  JSX element class does not support attributes because it does not have a 'props' property.

Eğer HinfactIcon'un yorumunu kaldırırsam, o zaman 4 hata alıyorum, HinfactText ile tamamen aynı olan ama HinfactIcon için olan - bu yüzden gereksiz logları kaldırmak için yorum satırına aldım :)

Ama şimdi, eğer HinfactText.jsx içinde kullanılan kodu Test.jsx adlı bir dosyaya kopyalayıp yapıştırırsam, ancak ButtonWithBigIconAndSmallText.tsx ile aynı klasörde olursa, her şey mükemmel şekilde çalışıyor!

Neden? İçerik tamamen aynı!

interface Props {
  iconName: string;
  iconType?: string;
  text: string;
  onPress?(evt: GestureResponderEvent): void;
  style?: any;
}

const ButtonWithBigIconAndSmallText: FC<Props> = ({
  iconName, iconType, text, onPress, style,
}): ReactElement => (
  <TouchableOpacity onPress={onPress} style={{ ...styles.button, ...style }}>
    <Test style={{
      textTransform: 'uppercase',
      fontSize: 9,
      fontWeight: 'bold',
    }}
    >
      {text}
    </Test>
  </TouchableOpacity>
);

İşte mimari

src/
   Online/
         ButtonWithBigIconAnsSmallText.tsx
         Test.jsx
   Components/
         HinfactText.jsx

package.json :

"dependencies": {
    "@types/jest": "^27.0.3",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "@types/react-native": "^0.66.8",
    "@types/react-test-renderer": "^17.0.1",
    "prop-types": "^15.7.2",
    "react": "^17.0.2",
    "react-devtools-core": "^4.14.0",
    "react-dom": "^17.0.2",
    "react-native": "^0.66.0",
    "typescript": "^4.5.2",
    //...
  },
  "devDependencies": {
    "@babel/core": "^7.14.3",
    "@babel/eslint-parser": "^7.14.3",
    "@testing-library/jest-native": "^4.0.2",
    "@testing-library/react-native": "^9.0.0",
    "@typescript-eslint/eslint-plugin": "^5.6.0",
    "@typescript-eslint/parser": "^5.6.0",
    //...
  },

tsconfig.json :

{
  "compilerOptions": {
    "target": "es2017",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "lib": ["es2017"],                        /* Specify library files to be included in the compilation. */
    "allowSyntheticDefaultImports": true,
    "allowJs": true,                          /* Allow javascript files to be compiled. */
    "jsx": "react-native",                    /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "outDir": "out",                           /* Redirect output structure to the directory. */
    "skipLibCheck": true,                     /* Do not check libraries */
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "esModuleInterop": true,
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "exclude": [
    "node_modules",
    "./node_modules",
    "node_modules/*",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}


Cevap #1

Bu konu hakkında güncelleme, bileşenimi require kullanmadan neden içe aktaramadığımı nihayet buldum, sebep "moduleResolution": "node" idi. Satırı kaldırmak sorunu çözdü.