[英]Declaration merging for Joi types
I want to narrow the type
property of the ValidationErrorItem from Joi
using declaration merging.我想使用声明合并来缩小
Joi
的ValidationErrorItem的type
属性。
The interface in Joi looks like this: Joi 中的界面如下所示:
declare namespace Joi {
interface ValidationErrorItem {
message: string;
path: Array<string | number>;
type: string;
context?: Context;
}
}
My index.d.ts
in src/types
looks like this:我在
src/types
中的index.d.ts
如下所示:
import { Context } from 'joi'
declare namespace Joi {
type ValidationErrorItemType = 'any.required' | 'date.format'
export interface ValidationErrorItem {
message: string
path: Array<string | number>
type: ValidationErrorItemType
context?: Context
}
}
This is my include
in tsconfig.json
:这是我在
tsconfig.json
中include
的内容:
"include": ["src/**/*", "types/types.d.ts"]
However, VS Code still shows type
to be of type string instead of ValidationErrorItem
and when using it in a switch
statement I can still use any string without getting compiler warnings.但是,VS Code 仍然显示
type
为 string 而不是ValidationErrorItem
类型,并且在switch
语句中使用它时,我仍然可以使用任何字符串而不会收到编译器警告。
Update更新
This is my tsconfig.json
这是我的
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"declaration": true,
"target": "es6",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": ["node_modules/*", "src/types/*"]
}
},
"include": ["src/**/*", "types/joi.ts"]
}
This is my joi.d.ts
based on the answer from @tymzap:这是我的
joi.d.ts
基于@tymzap 的回答:
declare module 'joi' {
// full path to joi typings is used to avoid circular import path
import type { Context } from 'joi/lib/index'
export { default } from 'joi/lib/index'
type ValidationErrorItemType = 'any.required' | 'date.format'
export type ValidationErrorItem = {
message: string
path: Array<string | number>
type: ValidationErrorItemType
context?: Context
}
}
This is my sample usage:这是我的示例用法:
error.details.map((i) => {
const x: ValidationErrorItem = i as ValidationErrorItem
switch (x.type) {
case 'any.required':
break
default:
break
}
})
You can't narrow the type using interface merging.您不能使用接口合并来缩小类型。 This operation extends types, not overrides them.
此操作扩展类型,而不是覆盖它们。 Extending
ValidationErrorItemType
with string
gives ValidationErrorItemType | string
用
string
扩展ValidationErrorItemType
给出ValidationErrorItemType | string
ValidationErrorItemType | string
, that's why you still can use any string
. ValidationErrorItemType | string
,这就是为什么你仍然可以使用任何string
。
To achieve this you can redeclare Joi module.为此,您可以重新声明 Joi 模块。 Modify the type to your needs and export it after reexporting original Joi typings.
根据您的需要修改类型并在重新导出原始 Joi 类型后将其导出。
joi.d.ts: joi.d.ts:
declare module 'joi' {
// full path to joi typings is used to avoid circular import path
import type { Context } from 'joi/lib/index';
export * from 'joi/lib/index';
export { default } from 'joi/lib/index';
type ValidationErrorItemType = 'any.required' | 'date.format';
export type ValidationErrorItem = {
message: string;
path: Array<string | number>;
type: ValidationErrorItemType;
context?: Context;
}
}
Test:测试:
import type { ValidationErrorItem } from 'joi';
const test: ValidationErrorItem = {
// error: Type '"wrong.type"' is not assignable to type 'ValidationErrorItemType'.
type: 'wrong.type',
message: 'dummy message',
path: ['dummy-path'],
};
This way you can effectively override given type from library, without merging with its original signature.这样,您可以有效地覆盖库中的给定类型,而无需与其原始签名合并。
Edit: Joi uses old export =
syntax, depending on your compiler settings this could lead to errors based on typings flavour incompatibility.编辑:Joi 使用旧的
export =
语法,这取决于您的编译器设置,这可能会导致基于类型不兼容的错误。 In this case you can add this line to tsconfig:在这种情况下,您可以将此行添加到 tsconfig:
{
"compilerOptions": {
"skipLibCheck": true
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.