typescript - 如何将具有动态属性名称的值分配给打字稿中的类
问题描述
我编写了一个代码,它使用 typescript 将 QueryArrayResult 映射到deno中的对象。
const mapDbResultToModelArray = <T>(dbResult: QueryArrayResult<Array<string>>): Array<T> => {
const objArr: Array<T> = [];
for (let i = 0; i < (dbResult.rowCount || 0); i++) {
const obj = {} as T;
for (let columnInfo of (dbResult.rowDescription || {columns:[]}).columns) {
//@ts-ignore
obj[columnInfo.name] = dbResult.rows[i][columnInfo.index - 1];
}
objArr[i] = obj;
}
return objArr;
}
但是这段代码有//@ts-ignore
一个问题,我不能指望返回 obj 的类型是 T。对象可以有空值
如何安全地分配具有动态属性名称的值,例如columnInfo.name
没有//@ts-ignore
解决方案
如果您只是想绕过 ts-ignore,您可以执行以下操作
- 使用绕过类型检查的函数
for (let columnInfo of (dbResult.rowDescription || {columns:[]}).columns) {
Object.assign(obj, {[columnInfo.name] : dbResult.rows[i][columnInfo.index - 1]});
}
- 强制转换为 T
for (let columnInfo of (dbResult.rowDescription || {columns:[]}).columns) {
obj[columnInfo.name as keyof T] = dbResult.rows[i][columnInfo.index - 1];
}
- 由于您将数组转换为
Array<T>
,因此您不需要将 obj 转换为 T
const obj: any = {};
for (let columnInfo of (dbResult.rowDescription || {columns:[]}).columns) {
obj[columnInfo.name] = dbResult.rows[i][columnInfo.index - 1];
}
objArr[i] = obj;
解释发生了什么...目前对 T 没有限制,说<T>
T 可以是string
, number
, object
, Symbol
.. 等。您可以T
使用extend
ie 添加限制。
<T extends object>
将确保 T 会从 type 下降object
。注意:这不会解决您的问题。extends
不一样equals
。即..在你原来的功能做
type T = Record<string, any>
const obj = {} as T;
也会解决你的问题。然而做
const mapDbResultToModelArray = <T extends Record<string, any>>(dbResult: QueryArrayResult<Array<string>>): Array<T> => {
const objArr: Array<T> = [];
for (let i = 0; i < (dbResult.rowCount || 0); i++) {
const obj = {} as T;
不会。您仍然会有索引错误。这是因为在前一个示例中T
确实是Record<string, any>
,但在梯形示例中T
仅继承自Record<string, any>
但仍可能是更具体的类型,即。T = Record<'key1', 'key2', any>
这就是为什么铸造obj[columnInfo.name as keyof T]
将始终有效的原因,因为如果键是,string
那么keyof T
将是string
,但如果键是,'key1' | 'key2'
那么keyof T
将是key1' | 'key2
因此,即使您输入得更好,您仍然可能会遇到问题,但希望您能更好地理解它们。
当我开始使用 TS 时,这样的事情确实看起来很烦人,但随着时间的推移,通常调查这样的问题可以帮助你更深入地理解代码。IE。即使您编写了代码并且您知道发生了什么,这在运行时很可能是正确的,但是 ts 会突出显示如果出现小错误可能会出错的地方。
因此,不要气馁,要求获得更深入的了解。
推荐阅读
- python - 如何将使用相同变量的两个 SeleniumLibrary 关键字组合成自定义关键字并在其他关键字中调用?
- javascript - 将配置文件移出项目根目录(webpack)
- python - 函数 replace( ) 似乎不起作用
- excel - 如何在 Excel 中使用 vba 从 Outlook 日历中获取存档的会议
- automated-tests - 如何使用 dataprovider 在测试注释中设置行数据?
- php - 如何解决“抱歉,您的会话已过期。请刷新并重试 Laravel 5 中的消息
- typo3 - Typo3 TypoScript 和带有 globalVar 的 AND 条件
- python - bdist_wheel:默认包含哪些文件?
- java - 如何通过 Hibernate 合并为字段设置默认 NULL 值
- c++ - 在 texture2D 中绘制线条和字符(DirectCompute HLSL 编程)