может быть создан с другим подтипом ограничения 'объект'

A есть ошибка проверки типов в рекурсивных типах.

Я пытаюсь написать типы для объекта стилей реагировать-JSS.

type StylesFn<P extends object> = (
  props: P
) => CSS.Properties<JssValue<P>> | number | string;

type JssValue<P extends object> =
  | string
  | number
  | Array<string | number>
  | StylesFn<P>;

// @ts-ignore
interface StylesObject<K extends string = any, P extends object = {}>
  extends Styles {
  [x: string]: CSS.Properties<JssValue<P>> | Styles<K, P>;
}
export type Styles<K extends string = any, P extends object = {}> = {
  [x in K]: CSS.Properties<JssValue<P>> | StylesObject<any, P> | StylesFn<P>
};

Работает нормально, но машинопись пишет ошибку. Я пользуюсь @ts-ignore, но это не модно

ERROR 24:11  typecheck  Interface 'StylesObject<K, P>' incorrectly extends interface 'Styles<any, {}>'.
  Index signatures are incompatible.
    Type 'Properties<JssValue<P>> | Styles<K, P>' is not assignable to type 'StylesFn<{}> | Properties<JssValue<{}>> | StylesObject<any, {}>'.
      Type 'Properties<JssValue<P>>' is not assignable to type 'StylesFn<{}> | Properties<JssValue<{}>> | StylesObject<any, {}>'.
        Type 'Properties<JssValue<P>>' is not assignable to type 'Properties<JssValue<{}>>'.
          Type 'JssValue<P>' is not assignable to type 'JssValue<{}>'.
            Type 'StylesFn<P>' is not assignable to type 'JssValue<{}>'.
              Type 'StylesFn<P>' is not assignable to type 'StylesFn<{}>'.
                Type '{}' is not assignable to type 'P'.
                  '{}' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'object'.

Что означает эта ошибка?

Ответ 1

Эта ошибка является предупреждением, что вашему универсальному типу P нельзя присвоить {}, поскольку универсальный тип P может быть более определенным (или ограниченным) типом.

Это означает, что значение {} не будет удовлетворять всем возможным типам, которые можно использовать для универсального типа P.

Например, у меня может быть универсальный подобный (с той же ошибкой):

function fn<T extends boolean>(obj: T = false) {
}

и вы можете иметь тип, который является более конкретным, чем логическое значение, например:

type TrueType = true;

и если вы передадите его Общей функции fn:

const boolTrue: TrueType = true;
fn(boolTrue);

присвоение false не соответствует TrueType, даже если TrueType учитывает ограничение универсального T extends boolean

Для получения дополнительной информации об этом сообщении об ошибке см. проблему, которая предложила это сообщение об ошибке https://github.com/Microsoft/TypeScript/issues/29049.