TypeScript版本: 2.2.0
代码
// A *self-contained* demonstration of the problem follows...
type DeepReadonly<T> = {
readonly [K in keyof T]: DeepReadonly<T[K]>;
}
interface FieldBrand {
" do not use ": void;
}
type FieldId = number & FieldBrand;
interface DefOne {
field: string | FieldId;
kind: string;
}
interface DefTwo {
field?: undefined; // Allow discriminant checks on 'field'
value: string;
}
type Def = DefOne | DefTwo;
interface State {
a?: Def;
b?: Def;
}
type ROState = DeepReadonly<State>;
function lookupName(f: FieldId): string {
return "";
}
function remapFieldsToNames(channels: ROState): ROState {
const newState: State = {};
for (const k of Object.keys(channels)) {
const key = k as keyof ROState;
const ch = channels[key];
let replacement: ROState[typeof key] | undefined = undefined;
if (ch) {
if (ch.field) {
const f = ch.field;
if (typeof f === "number") {
f; // Should be FieldId or number, not never!
replacement = { ...ch, field: lookupName(f) };
}
else if (typeof f === "string") {
f; // correct
}
}
}
newState[k] = replacement || channels[k];
}
return newState;
}
预期行为:
上述代码中没有类型错误,并且在typeof f === "number"
检查之后的f
既可以是数字也可以是FieldId
。
实际行为:
replacement = { ...ch, field: lookupName(f) };
存在类型错误,而f
的类型是never
。
2条答案
按热度按时间fruv7luv1#
这里还有一些奇怪的操作,
DeepReadonly
在函数体内部的 quickinfo 中省略了通用参数,这可能与相关/应该被调查:jtw3ybtb2#
DeepReadonly
和带标签的数字之间的奇怪之处实际上导致了每次我试图将深度只读结构分配给普通结构时,类型不兼容。