TypeScript + React:正确定义defaultProps

时间:2016-10-10 14:22:24

标签: javascript reactjs typescript

假设你定义你的组件:

interface IProps {
  req: string;
  defaulted: string;
}

class Comp extends React.Component<IProps, void> {
  static defaultProps = {
    defaulted: 'test',
  };

  render() {
    const { defaulted } = this.props;

    return (
      <span>{defaulted.toUpperCase()}</span>
    );
  }
}

当您想要使用它时,TypeScript需要defaulted道具,即使它已在defaultProps中定义:

<Comp req="something" />  // ERROR: TypeScript: prop 'defaulted' is required

但是,如果你这样定义道具界面:

interface IProps {
  req: string;
  defaulted?: string;  // note the ? here
}

然后你不能在:

中使用它
render() {
  const { defaulted } = this.props;  // ERROR: prop 'defaulted' possibly undefined

  return (
    <span>{defaulted.toUpperCase()}</span>
  );
}

如何正确定义IProps,defaultProps和组件以使类型有意义?

修改

我使用strictNullChecks标志。

3 个答案:

答案 0 :(得分:4)

我有一个使用以下代码的示例(ComponentBase只是我在React.Component周围的包装器)。

修改更新的代码以使用'strictNullChecks'设置

interface IExampleProps {
    name: string;
    otherPerson?: string;
}

/**
 * Class with props with default values
 *
 * @class Example
 * @extends {ComponentBase<IComponentBaseSubProps, {}>}
 */
export class Example extends ComponentBase<IExampleProps, {}> {
    public static defaultProps: IExampleProps = {
        otherPerson: "Simon",
        name: "Johnny"
    };

    constructor(props: IExampleProps) {
        super(props);
    }

    public render(): JSX.Element {
        const person: string = this.props.otherPerson === undefined ? "" : this.props.otherPerson;
        return(
            <div>
                <h1><small>Message by ComponentBaseSub: Hello {this.props.name} and {person} </small></h1>
            </div>
        );
    }
}

使用Visual Studio Code,TypeScript 2.0.3,TSLint 0.5.39。

时没有问题

答案 1 :(得分:1)

更简单的是

<span>{(defaulted as string).toUpperCase()}</span>

与属性的工作方式相同。如果Foo需要barProp属性,但Parent不需要defaultPropsParent<Foo barProp={this.props.barProp as string} /> 的渲染方法可以执行

String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_SMS, Manifest.permission.CAMERA};

    if(!hasPermissions(this, PERMISSIONS)){
        ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
    }



public static boolean hasPermissions(Context context, String... permissions) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

答案 2 :(得分:1)

如果您确定prop将具有默认值,则可以使用null断言类型运算符,如下所示:

render() {
  const { defaulted } = this.props;
  return (
    <span>{defaulted!.toUpperCase()}</span>
  );
}