There is such interface
export interface DocExportRequest {
id: string
type: 'PDF' | 'CSV'
[k: string]: any
}
Also I have jeneric type, which exclude [k: string] property
// 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
Also I use ForkTsCheckerWebpackPlugin with config
const config = {
async: isDevelopment,
useTypescriptIncrementalApi: true,
checkSyntacticErrors: true,
reportFiles: ['**', '!**/__tests__/**', '!**/?(*.)(spec|test).*', '!**/src/setupProxy.*', '!**/src/setupTests.*'],
silent: true,
};
and my tsconfig is
{
"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"]
}
When I am applaying KnownKeys to DocExportRequest,
type TDocExportReq = KnownKeys<DocExportRequest>
I expect that it will be
type TDocExportReq {
id: string
type: 'PDF' | 'CSV'
}
But it return 'never'. Why?
Before that, the project was bootstrapped with create-react-app with similar configs, and all types were defined correct.
CodePudding user response:
That implementation of KnownKeys<T>
was unfortunately broken in TypeScript 4.3; see microsoft/TypeScript#44142 for the relevant bug report. It's marked as "Needs Investigation" so the TS team isn't even sure if it qualifies as a bug or a new limitation, and nobody's even 100% sure what broke it.
Luckily there is a different implementation that works in TypeScript 4.2 and above, which uses key remapping to suppress index signatures:
type KnownKeys<T> = keyof { [P in keyof T as
string extends P ? never : number extends P ? never : P
]: T[P]; };
And you can verify that this works:
type TDocExportReq = KnownKeys<DocExportRequest>
// type TDocExportReq = "id" | "type"