简体   繁体   English

React-Typescript:如何输入默认道具?

[英]React-Typescript: How do I type a default prop?

Let's say I have this component class: 假设我有这个组件类:

interface SomeComponentProps {
  someOptionalProperty?: string;
}
interface SomeComponentState { /* ... */ }

class SomeComponent extends React.Component<SomeComponentProps, SomeComponentState> {
  static defaultProps = {
    someOptionalProp = 'some default value',
  }

  method() {
    const shouldNotBeOptional = this.props.someOptionalProp;
  }
}

How can I assert that this.props.someOptionalProp is not undefined within the class but is also optional when trying to using the component? 我如何断言this.props.someOptionalProp在类中不是未定义的,但是在尝试使用组件时也是可选的?

What I've been doing is just ignoring defaultProps altogether by creating getters that 我一直在做的只是通过创建获取器来完全忽略defaultProps

return `this.props.someOptionalProp || 'the default value'`;

but I'd like to use defaultProps because my team uses it. 但我想使用defaultProps因为我的团队正在使用它。

Not really possible as it stands with TS 2.8.3, there are some issues open about it already TS 2.8.3确实不可行,但已经存在一些问题

On react types: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11640 关于反应类型: https : //github.com/DefinitelyTyped/DefinitelyTyped/issues/11640

On the TS repo: https://github.com/Microsoft/TypeScript/issues/23812 在TS回购上: https : //github.com/Microsoft/TypeScript/issues/23812

Best you can achieve currently I believe is by using the ! 我相信您目前可以实现的最好成绩是! operator to tell the compiler that you know something can't be null 运算符,告诉编译器您知道某些内容不能为null

const shouldNotBeOptional = this.props.someOptionalProp!;

You could use a higher order component (HOC) that will just change the type of the props to be optional where they are present in defaultProps 您可以使用更高阶的组件(HOC),它将仅将props的类型更改为defaultProps中存在的props的类型。

interface SomeComponentProps {
    required: string;
    someOptionalProperty: string;
    trulyOptional?: string;
}
interface SomeComponentState { /* ... */ }

class SomeComponent extends React.Component<SomeComponentProps, SomeComponentState> {
    static defaultProps = {
        someOptionalProperty : 'some default value',
    }

    method() {
        const shouldNotBeOptional = this.props.someOptionalProperty;
    }
}

type SameTypeOrCustomError<T1, T2> = T1 extends T2 ? T2 extends T1 ? T1 : "Error Different Types": "Error Different Types";
type FilterOptional<T> = Exclude<{ [P in keyof T]: undefined extends T[P]? P: never }[keyof T], undefined>;

type d = FilterOptional<SomeComponentProps>
type PropsWithDefault<TProps extends TDefaults, TDefaults> = 
    { [P in Exclude<keyof TProps, keyof TDefaults | FilterOptional<TProps>>]: TProps[P] } &
    { [P in keyof TDefaults | FilterOptional<TProps>]?: TProps[P] }; 

type ReactProps<T> = T extends React.Component<infer Props, any> ? Props: never;
type ReactState<T> = T extends React.Component<any, infer TState> ? TState: never;
type ChangeReactProps<TComponent extends React.Component<any, any>, TNewProps> = {
    new (props: TNewProps, context?: any) : React.Component<TNewProps, ReactState<TComponent>>
};

function withDefaults<T extends { new (...args: any[]) : any, defaultProps: Partial<ReactProps<InstanceType<T>>> }>(ctor: T) 
    : ChangeReactProps<InstanceType<T>, PropsWithDefault<ReactProps<InstanceType<T>>, T['defaultProps']>>  {
    return ctor; // we just chage type, we can return the same class 
}


const SomeComponent2 = withDefaults(SomeComponent);

let d = <SomeComponent2  required=""  /> //ok 
let x = <SomeComponent2  required="" trulyOptional="" /> //ok 

I use a higher order component with Typescript 2.8 in my codebase: 我在代码库中使用Typescript 2.8的高阶组件:

const withDefaultProps = <P extends object, DP extends Partial<P>>(
  defaultProps: DP,
  component: React.ComponentType<P>
) => {
  type ActualProps = Partial<DP> & Pick<P, Exclude<keyof P, keyof DP>>
  component.defaultProps = defaultProps
  return component as React.ComponentType<ActualProps>
}

interface IComponentProps {
  someOptionalProp: string
}

class SomeComponent extends React.Component<IComponentProps, {}> {
  method() {
    // this is always defined
    const shouldNotBeOptional = this.props.someOptionalProp;
  }
}

// when using this like <SomeComponent />, someOptionalProp is optional
export default withDefaultProps(
  { someOptionalProp: 'defaultValue' },
  SomeComponent
)

This issue has been discussed and resolved in here . 这个问题已经在这里讨论和解决。 Now you simply can do that: 现在,您只需执行以下操作:

interface Props {
  thing: string; // note: not optional within class, but is optional when writing due to the default
}

class Thing extends React.Component<Props> {
   static defaultProps = {
      thing: 'hello'
   }

  render() {
    console.log(this.props.thing) // strict type from `Props`
    // ...
 }
}
// ..
<Thing /> // works, thanks to `defaultProps`

It works for me in Typescript 3.1.6 and React 16.5.0 它适用于Typescript 3.1.6和React 16.5.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 react-typescript 中设置 HOC 中的道具类型? - How can I set the props type in HOC in react-typescript? 如何使用 CRA 向 react-typescript 项目添加类型声明 - how to add type declaration to react-typescript project with CRA 如何在箭头 function React-TypeScript 中返回通用类型 - How to return Generic Type in arrow function React-TypeScript 如何为React props定义TypeScript类型,只有在将prop A传递给组件时,才会接受prop B? - How do I define a TypeScript type for React props where prop B is only accepted if prop A is passed to a component? 如果与 setInterval、react-typescript 一起使用,则为 useRef 键入 - type for useRef if used with setInterval, react-typescript React-TypeScript:这个 JSX 标签的 &#39;children&#39; 属性需要一个 &#39;ReactNode&#39; 类型的子节点,但提供了多个子节点 - React-TypeScript: This JSX tag's 'children' prop expects a single child of type 'ReactNode', but multiple children were provided 如何将 react-typescript className 制作为数组 - How to make react-typescript className to array React-typescript chart.js 错误“类型”在类型中丢失 - React-typescript chart.js error 'type' is missing in type 如何在 React 和 Typescript 中将组件作为道具传递? - How do I pass a component as a prop in React and Typescript? (React-Typescript)如何声明和显示具有未知键数和名称的 object 的泛型类型? - (React-Typescript) how to declare and display generic type of object with unknown number and name of keys?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM