Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix link type error #262

Merged
merged 1 commit into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/components/src/components/link/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import classnames from 'classnames';
import { TLinkProps } from './interface';
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/components/link/interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/ban-types */
import { OverrideProps } from '../../typings/OverridableComponent';
import { OverrideProps } from '../../utils/type';

export type HtmlElement = keyof React.ReactHTML;

Expand Down
66 changes: 66 additions & 0 deletions packages/components/src/utils/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,75 @@ export const tupleNum = <T extends number[]>(...args: T) => args;
* https://stackoverflow.com/a/59187769
* Extract the type of an element of an array/tuple without performing indexing
*/
// eslint-disable-next-line no-shadow
export type ElementOf<T> = T extends (infer E)[] ? E : T extends readonly (infer E)[] ? E : never;

/**
* https://github.com/Microsoft/TypeScript/issues/29729
*/
// eslint-disable-next-line @typescript-eslint/ban-types
export type LiteralUnion<T extends U, U> = T | (U & {});

/**
* 原 OverridableComponent.d
*/
export interface OverridableTypeMap {
// eslint-disable-next-line @typescript-eslint/ban-types
props: {};
defaultComponent: React.ElementType;
}

/**
* 基本的合法的组件 props
*/
// prettier-ignore
export interface CommonProps {
className?: string;
style?: React.CSSProperties;
}

/**
* 大部分组件都会有的 props 类型
*/
// prettier-ignore
export type BaseProps<M extends OverridableTypeMap> =
& M['props']
& CommonProps;

/**
* 没有使用 `component={Component}` 时的 Props 定义
*/
// prettier-ignore
export type DefaultComponentProps<M extends OverridableTypeMap> =
& BaseProps<M>
& Omit<React.ComponentPropsWithRef<M['defaultComponent']>, keyof BaseProps<M>>;

/**
* 使用 `component={Component}` 时的 Props 定义.
*/
// prettier-ignore
export type OverrideProps<
M extends OverridableTypeMap,
C extends React.ElementType
> = (
& BaseProps<M>
& Omit<React.ComponentPropsWithRef<C>, keyof CommonProps>
);

/**
* 定义通过 'component' prop 可进行根组件组件类型控制的组件
*
* 根据 component 的类型来定义 props
*/
export interface OverridableComponent<M extends OverridableTypeMap> {
<C extends React.ElementType>(
props: {
/**
* 用于组件根节点的 component
* 可以是一个 HTML 元素字符串或一个自定义的组件
*/
component: C;
} & OverrideProps<M, C>
): React.ElementType;
(props: DefaultComponentProps<M>): React.ElementType;
}