Цель
Упростите следующую ситуацию
// Simplify
loading ? <Loading/> : (
<Fragment>
....
</Fragment>
)
// Into something like
<LoadingContent loading={loading}>
{() => (
<Fragment>
...
</Fragment>
)}
</LoadingContent>
Проблема
если условие загрузки является атрибутом объект, используемый для размеченного объединения , свойства доступа, основанные на истинности этого атрибута, не будут переданы, и он не будет компилироваться.
Текущее решение
Используйте короткое замыкание оценки с помощью логического &&, но это дублирует условие, и цель состоит в том, чтобы упростить его.
<LoadingContent loading={loading}>
{() => loading && (
<Fragment>
...
</Fragment>
)}
</LoadingContent>
Из предложения:
Проблема, общий тип c должен быть указан и не может быть выведен из-за https://github.com/microsoft/TypeScript/issues/16597
interface LoadingDiscriminatedContentProps<
A extends string,
S,
SS extends S,
O extends { [P in A]: S }
> {
object: O;
attribute: A;
discriminant: SS;
children: (loaded: Extract<O, O & { [P in A]: SS }>) => React.ReactElement;
}
export function LoadingDiscriminatedContent<
A extends string,
S,
SS extends S,
O extends { [P in A]: S }
>({
object,
attribute,
discriminant,
children
}: LoadingDiscriminatedContentProps<A, S, SS, O>): React.ReactElement {
if (object[attribute] === (discriminant as S)) {
return children(object as Extract<O, O & { [P in A]: SS }>);
}
return <Loading />;
}