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ü.