-- ROBLOX deviation: this is a class export upstream, so optional overrides are nil-able, and it's extensible by default

export type React_Component<Props, State = nil> = {
	-- fields
	props: Props,
	state: State,

	-- action methods

	setState: (
		self: React_Component<Props, State>,
		partialState: State | ((State, Props) -> State?),
		callback: (() -> any)?
	) -> (),

	forceUpdate: (callback: ((() -> ())?)) -> (),

	-- lifecycle methods

	init: ((props: Props?, context: any?) -> ())?,
	render: (self: React_Component<Props, State>) -> React_Node,
	componentWillMount: ((self: React_Component<Props, State>) -> any)?,
	UNSAFE_componentWillMount: ((self: React_Component<Props, State>) -> any)?,
	componentDidMount: ((self: React_Component<Props, State>) -> any)?,
	componentWillReceiveProps: ((
		self: React_Component<Props, State>,
		nextProps: Props,
		nextContext: any
	) -> any)?,
	UNSAFE_componentWillReceiveProps: ((
		self: React_Component<Props, State>,
		nextProps: Props,
		nextContext: any
	) -> any)?,
	shouldComponentUpdate: ((
		self: React_Component<Props, State>,
		nextProps: Props,
		nextState: State,
		nextContext: any
	) -> boolean)?,
	componentWillUpdate: ((
		self: React_Component<Props, State>,
		nextProps: Props,
		nextState: State,
		nextContext: any
	) -> any)?,
	UNSAFE_componentWillUpdate: ((
		self: React_Component<Props, State>,
		nextProps: Props,
		nextState: State,
		nextContext: any
	) -> any)?,
	componentDidUpdate: ((
		self: React_Component<Props, State>,
		prevProps: Props,
		prevState: State,
		prevContext: any
	) -> any)?,
	componentWillUnmount: ((self: React_Component<Props, State>) -> any)?,
	componentDidCatch: ((
		self: React_Component<Props, State>,
		error: Error,
		info: {
			componentStack: string,
		}
	) -> any)?,
	getDerivedStateFromProps: ((props: Props, state: State) -> any)?,
	getDerivedStateFromError: ((error: Error) -> any)?,

	-- long tail of other stuff not modeled very well

	-- ROBLOX deviation: this field is only used in relation to string refs, which we do not support
	-- refs: any,
	-- context: any,
	getChildContext: (self: React_Component<Props, State>) -> any,
	-- statics
	__componentName: string,
	displayName: string?,
	childContextTypes: any?,
	contextTypes: any?,
	propTypes: any?,

	-- ROBLOX FIXME: this is a legacy Roact field and should be removed in React 18 Lua
	validateProps: (Props) -> (boolean, string?)?,

	-- We don't add a type for `defaultProps` so that its type may be entirely
	-- inferred when we diff the type for `defaultProps` with `Props`. Otherwise
	-- the user would need to define a type (which would be redundant) to override
	-- the type we provide here in the base class.
	-- ROBLOX deviation: Luau doesn't do the inference above
	defaultProps: Props?,
	-- ROBLOX deviation: class export allows assigning additional custom instance fields
	[string]: any,
}
