@cloudz

Почему возвращается не корректный тип?

Всем привет!
Есть такой интерфейс
export interface DocExportRequest {
  id: string
  type: 'PDF' | 'CSV'
  [k: string]: any
}


Написан дженерик оставляющий только реально существующие свойства
// see https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-414782407
// disables `[k: string]: any;` indexing
export type KnownKeys<T> = {
  [K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U }
  ? U
  : never


Используется ForkTsCheckerWebpackPlugin с такими настройками

const config = {
  async: isDevelopment,
  useTypescriptIncrementalApi: true,
  checkSyntacticErrors: true,
  reportFiles: ['**', '!**/__tests__/**', '!**/?(*.)(spec|test).*', '!**/src/setupProxy.*', '!**/src/setupTests.*'],
  silent: true,
};


и такой tsconfig
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@assets/*": ["src/assets/*"],
      "@src/*": ["src/*"]
   },
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "typeRoots": [
      "./node_modules/@types"
    ],
    "types": [
      "node",
      "webpack-env",
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "jsx": "react"
  },
  "include": ["src", "public"]
}


При попытке применить KnownKeys к интерфейсу DocExportRequest,
type TDocExportReq = KnownKeys<DocExportRequest>
ожидаю что будет
type TDocExportReq {
  id: string
  type: 'PDF' | 'CSV'
}

Но он возвращает 'never'. Почему так происходит?

До этого этот проект был на create-react-app с такими же конфигами, и типы верно выделялись.
  • Вопрос задан
  • 57 просмотров
Решения вопроса 1
@cloudz Автор вопроса
Это "поломано" в новых версиях typescript. https://github.com/microsoft/TypeScript/issues/44143
В версиях ^4.2 можно пользоваться альтернативными решениями, например

type KnownKeys<T> = keyof { [P in keyof T as
    string extends P ? never : number extends P ? never : P
    ]: T[P]; };


или

type KeyToKeyNoIndex<T> = {
  [K in keyof T]: string extends K ? never : number extends K ? never : K;
};
type ValuesOf<T> = T extends { [K in keyof T]: infer U; } ? U : never;
export type KnownKeys<T> = ValuesOf<KeyToKeyNoIndex<T>>;
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы