‘keyof typeof value’ приводит к результату другого типа по сравнению с ‘keyof interface’

#typescript

#typescript

Вопрос:

Я изначально определил тип пересечения типа DOMRectReadOnly и StyleProperties , как показано ниже, какой тип результатов "size" | "start" | "end" .

 interface StyleProperties {
    size: ["width", "height"];
    start: ["left", "top"],
    end: ["right", "bottom"];
}

export const StyleProperties: StyleProperties = {
    size: ["width", "height"],
    start: ["left", "top"],
    end: ["right", "bottom"]
};

type DOMRectStyleProperties = {
  [P in keyof StyleProperties]:
    (StyleProperties[P][0] | StyleProperties[P][1]) extends keyof DOMRectReadOnly
    ? P
    : never
}[keyof StyleProperties];
 

Но я хочу удалить interface StyleProperties часть и заменить ее использование на typeof StyleProperties , как показано ниже, но это приводит к типу never .

 export const StyleProperties = {
    size: ["width", "height"],
    start: ["left", "top"],
    end: ["right", "bottom"]
};

type DOMRectStyleProperties = {
  [P in keyof typeof StyleProperties]:
    (typeof StyleProperties[P][0] | typeof StyleProperties[P][1]) extends keyof DOMRectReadOnly
    ? P
    : never
}[keyof typeof StyleProperties];
 

Что не так в моем использовании typeof ключевого слова?

Ответ №1:

В вашем использовании нет ничего плохого typeof . Проблема в том, что типы, для которых typescript может сделать вывод StyleProperties , менее строгие, чем хотелось бы:

 const StyleProperties = {
    size: ["width", "height"],
    start: ["left", "top"],
    end: ["right", "bottom"]
};
type Example = typeof StyleProperties;
 

Если вы посмотрите на это, вы увидите, что теперь эти свойства string[] являются не типизированными кортежами. Если вы сообщите typescript, что это константы и не будут меняться, вы должны получить нужный тип:

 const StyleProperties = {
    size: ["width", "height"] as const,
    start: ["left", "top"] as const,
    end: ["right", "bottom"] as const,
};
type Example = typeof StyleProperties;
 

И при правильном типе использование typeof должно делать то, что вы хотите!