[英]React-Typescript: How do I type a default prop?
假设我有这个组件类:
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;
}
}
我如何断言this.props.someOptionalProp
在类中不是未定义的,但是在尝试使用组件时也是可选的?
我一直在做的只是通过创建获取器来完全忽略defaultProps
return `this.props.someOptionalProp || 'the default value'`;
但我想使用defaultProps
因为我的团队正在使用它。
TS 2.8.3确实不可行,但已经存在一些问题
关于反应类型: https : //github.com/DefinitelyTyped/DefinitelyTyped/issues/11640
在TS回购上: https : //github.com/Microsoft/TypeScript/issues/23812
我相信您目前可以实现的最好成绩是!
运算符,告诉编译器您知道某些内容不能为null
const shouldNotBeOptional = this.props.someOptionalProp!;
您可以使用更高阶的组件(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
我在代码库中使用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
)
这个问题已经在这里讨论和解决。 现在,您只需执行以下操作:
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`
它适用于Typescript 3.1.6和React 16.5.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.