【发布时间】:2019-03-25 00:46:38
【问题描述】:
我正在为 TypeScript 的类型检查而苦苦挣扎。例如以下代码:
export function deepClone<T>(obj: T): T { // make sure that deepClone generates the same type as obj
if (obj == null || typeof obj !== 'object') {
return obj;
}
switch (Object.prototype.toString.call(obj)) {
case '[object Array]': {
const result = new Array(obj.length);
for (let i=0; i<result.length; ++i) {
result[i] = deepClone(obj[i]);
}
return result as any as T;
}
// Object.prototype.toString.call(new XxxError) returns '[object Error]'
case '[object Error]': {
const result = new obj.constructor(obj.message);
result.stack = obj.stack; // hack...
return result;
}
case '[object Date]':
case '[object RegExp]':
case '[object Int8Array]':
case '[object Uint8Array]':
case '[object Uint8ClampedArray]':
case '[object Int16Array]':
case '[object Uint16Array]':
case '[object Int32Array]':
case '[object Uint32Array]':
case '[object Float32Array]':
case '[object Float64Array]':
case '[object Map]':
case '[object Set]':
return new obj.constructor(obj);
case '[object Object]': {
const keys = Object.keys(obj);
const result: any = {};
for (let i=0; i<keys.length; ++i) {
const key = keys[i];
result[key] = deepClone(obj[key]);
}
return result;
}
default: {
throw new Error("Unable to copy obj! Its type isn't supported.");
}
}
}
我在const result = new Array(obj.length) 上遇到错误。我知道 obj 的类型是 any[] 但 ts 编译器无法识别它。我必须写丑陋的const tmp = obj as any as any[],但这会导致额外的无用代码生成,或者我必须在使用obj的每一行中写obj as any as whatever
写function deepClone<T extends any>(obj: T): T 可以,但它会禁用大多数类型检查。
另一种情况:
const el = document.getElementById('sth');
switch (el.tagName) {
case 'INPUT': // Now I know el is a HTMLInputElement element
el.value = '123'; // Error: HTMLElement doesn't contain property 'value'
(el as HTMLInputElement).value = '123'; // works
(el as HTMLInputElement).valueAsNumber = 123; // again
(el as HTMLInputElement).valueAsDate = xxx; // unacceptable
【问题讨论】:
-
stackoverflow.com/questions/40081332/… 使用
is关键字而不是与字符串化构造函数进行比较,这太可怕了 -
你的意思是instanceof吗?
-
如何将
is与switch 语句一起使用?或者至少不用写另一个新函数?
标签: javascript typescript