作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面给出了简化问题所需的代码框架。基本上,可以有不同类型的 Source
对象。为简单起见,下面的代码中显示了两种类型的源:DirectSource
和 IndirectSource
。函数 sourceAdapter()
接受 Source
和其他辅助参数。
在示例中:如果缺少参数 key
,则 Source
必须是 DirectSource
;如果 key
是单个字符串值,则 Source
必须是 IndirectSource
,并且在这两种情况下,代码都会执行必要的调整并返回 DirectSource
对象。如果 key
是一个数组,则 Source
应该是 IndirectSource
,它也是函数的返回值。
type KeyMap<T> = { [key in keyof T]: number };
type DirectSource = {
value: number;
otherFieldsAndMethods: any;
};
type IndirectSource<T extends object> = {
kvMap: KeyMap<T>;
otherFieldsAndMethods: any;
};
type Source<T extends number | object> = T extends object ? IndirectSource<T> : DirectSource;
// overloads
function sourceAdapter(src: Source<number>): DirectSource;
function sourceAdapter<T extends object>(src: Source<T>, key: keyof T): DirectSource;
function sourceAdapter<T extends object>(src: Source<T>, key: (keyof T)[]): IndirectSource<T>;
function sourceAdapter<T extends number | object>(
src: Source<T>,
key?: keyof T | (keyof T)[]
): T extends object ? IndirectSource<T> : DirectSource {
if (key) { // According to function overloads Source must be an IndirectSource
if (key instanceof Array) { // Config and return IndirectSource
const kvMap = key.reduce((ac, s) => {
ac[s] = (src as any).kvMap[s];
return ac;
}, {} as any);
// ******Error here:
// Type 'T' does not satisfy the constraint 'object'.
let ret: IndirectSource<T> = {
kvMap,
otherFieldsAndMethods: src.otherFieldsAndMethods
};
return ret;
} else { // Config and return DirectSource
let directSource = {
otherFieldsAndMethods: src.otherFieldsAndMethods,
value: (src as IndirectSource<any>).kvMap[key],
};
return directSource; // ******Error here: assignability
}
} else { // Source is a DirectSource, simply return the src.
return src;
}
}
<小时/>
出现错误的行用星号标记。 This is the link to the playground.
最佳答案
最简单、最干净的方法是将 ReturnType 更改为联合。享受。 Playground link
type KeyMap<T> = { [key in keyof T]: number };
type DirectSource = {
value: number;
otherFieldsAndMethods: any;
};
type IndirectSource<T extends object> = {
kvMap: KeyMap<T>;
otherFieldsAndMethods: any;
};
type Source<T extends number | object> = T extends object ? IndirectSource<T> : DirectSource;
// overloads
function sourceAdapter(src: Source<number>): DirectSource;
function sourceAdapter<T extends object>(src: Source<T>, key: keyof T): DirectSource;
function sourceAdapter<T extends object>(src: Source<T>, key: (keyof T)[]): IndirectSource<T>;
function sourceAdapter<T extends object>(
src: Source<T>,
key?: keyof T | (keyof T)[]
): IndirectSource<T> | DirectSource {
if (key) { // According to function overloads Source must be an IndirectSource
if (key instanceof Array) { // Config and return IndirectSource
const kvMap = key.reduce((ac, s) => {
ac[s] = (src as any).kvMap[s];
return ac;
}, {} as any);
// Error here:
// Type 'T' does not satisfy the constraint 'object'.
let ret: IndirectSource<T> = {
kvMap,
otherFieldsAndMethods: src.otherFieldsAndMethods
};
return ret as IndirectSource<T>;
} else { // Config and return DirectSource
let directSource = {
otherFieldsAndMethods: src.otherFieldsAndMethods,
value: (src as IndirectSource<any>).kvMap[key],
};
return directSource; // Error here: assignability
}
} else { // Source is a DirectSource, simply return the src.
return src;
}
}
关于javascript - 在 Typescript 中强制泛型类型参数满足基于函数重载定义的类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55754307/
我是一名优秀的程序员,十分优秀!