特定于平台的导入组件使用typescript进行本机反应

时间:2017-05-16 12:09:23

标签: typescript react-native

我正在使用native本地打字稿。我有一个具有以下结构的组件

component
    - component.ios.tsx
    - component.android.tsx

现在我要导入组件。所以,我这样做:

import component from '../component/component';

但它说:

[ts] Cannot find module ../component/component

位置正确。我需要在tslint文件中添加一些内容以使其理解。

我也尝试过:

let component = require('../component/component');

这没有给出打字稿错误。但它给出了运行时错误。

element type is invalid expected a string or a class/function but got undefined

有人遇到过这个问题吗? 谢谢。

5 个答案:

答案 0 :(得分:13)

一种烦人的做法是创建一个具有相同名称的声明文件。

component
- component.d.ts   <---
- component.android.tsx
- component.ios.tsx

然后

import { file } from "../group/file";

更新: 另一种方法是忽略其中之一的扩展名,然后打字稿将选择默认的扩展名。

  • component.tsx
  • component.android.tsx

Android将拾取特定的android文件,而iOS将默认为正常文件。

答案 1 :(得分:2)

在最新版本的React中,您可以使用 Suspense lazy 来避免过度输入等,例如,如果我想要组件 Touchable 使用适用于iOS和Android的特定代码,我的结构将如下所示:

V-bind:style=" $q.screen.lt.md ? 'height:600px' : ''"

在index.tsx上,代码如下所示:

- Touchable
   - index.tsx
   - Touchable.android.tsx
   - Touchable.ios.tsx
   - types.d.ts

因此,在我的应用程序中的任何位置上,我都想使用此组件:

import React, { FunctionComponent, lazy, Suspense } from 'react';
import { Platform, View } from 'react-native';

import { TouchableProps } from './types';

const TouchableComponent = lazy(() =>
  Platform.OS === 'ios'
    ? import('./Touchable.ios')
    : import('./Touchable.android'),
);

const Touchable: FunctionComponent<TouchableProps> = (props) => {
  return (
    <Suspense fallback={<View />}>
      <TouchableComponent {...props} />
    </Suspense>
  );
};

export default Touchable;

答案 2 :(得分:1)

这一切都有道理,因为../component/component.tsx处的文件不存在。

Haven没有尝试,但这可以学习TS来理解这样的进口

{
    "compilerOptions": {
        "paths": {
            "*": ["*", "*.ios", "*.android"]
        }
   }
}

答案 3 :(得分:0)

TypeScript小组明确指出it's a non-priority

  

我不认为我们可以做一个简单的更改来启用此方案。基于文件扩展名的假设已深入系统中,如果要启用此方案,则必须在输入文件,模块解析,类型检查,语言服务和输出生成中进行处理。同样,这不是一个简单的更改,重新布线整个编译器也不是一件容易的事。在#8328中,我概述了一些解决方法。

安德烈科(Andreyco)的解决方案首先是详细介绍by Mohammed Hegazy,但it only works for absolute paths

  
    

...就像@sondremare提到的那样,“路径”选项不适用于相对进口...是否有解决此问题的计划?

  
     

目前尚不清楚路径映射对相对路径的含义。所以真的没有计划。

osp's solution in a duplicate question来自最初提供的by Ryan Cavanaugh

# $str = "5,2,3,6,911,18,118,65,985,15...";
# Values separated by comma
# It can be from array
#     $str = implode(",",[5,2,3,6,911,18,118,65,985,15])

$str = "5,2,3,6,911,18,118,65,985,15";  

function get_titles($status,$arr){
    global $db;
    $sql = "SELECT * FROM arts WHERE status = :astatus ORDER BY FIELD(id,".$arr .") ASC";
    $st = $db->prepare($sql);
    $st->execute([":astatus" => $status]);
    ...
}

get_titles($status,$str)

我不确定该怎么做。

更多的是技术债务,但是如果您只是因为这里根本不知道如何获得任何进口而在这里,那么请记住,显式进口至少起了作用:

import * as ios from "./BigButton.ios"; 
import * as android from "./BigButton.ios"; 

declare var _test: typeof ios;
declare var _test: typeof android;

/// export to get the shape of the module
export * from "./BigButton.ios";

答案 4 :(得分:0)

假设您的组件名称为ProgressBar,因此创建index.d.ts并在下面的index.d.ts

中调整您的代码。
import {Component} from 'react';
import {Constructor, NativeMethodsMixin} from 'react-native';

export interface ProgressBarProps {
  progress: number;
}

declare class ProgressBarComponent extends Component<CheckBoxProps> {}

declare const ProgressBarBase: Constructor<NativeMethodsMixin> &
  typeof ProgressBarComponent;

export default class ProgressBar extends ProgressBarBase {}

所以您的组件文件夹应该看起来像

component/
 - index.android.tsx
 - index.ios.tsx
 - index.d.ts