typescript - TypeScript - 无法将字符串分配给通用对象的字符串值属性
问题描述
在 TypeScript 3.5.2 中,我编写了一个映射类型AssignableKeys<T>
,它生成所有类型的字符串值键的联合T
(即,所有键T[K]
都是字符串)。
此映射类型正确地防止将非字符串值属性分配给类型为 的变量AssignableKeys<T>
。
// Return a union of all keys in `T` that correspond to
// properties that can be assigned a value of type `TValue`
export type AssignableKeys<T, TValue> = {
[Key in keyof T]: TValue extends T[Key] ? Key : never
}[keyof T];
interface IObj {
A: string,
B: number,
}
// myKey must be a string-valued property of obj.
let myKey: AssignableKeys<IObj, string>;
// This works fine. "A" is a string-valued key of obj.
myKey = "A";
// This is an error (as expected). "B" is NOT a string-valued key of IObj.
myKey = "B";
但是,将字符串分配给与这些字符串值键之一对应的属性会失败并出现错误:
function setProp<T>(obj: T, key: AssignableKeys<T, string>) {
obj[key] = "banana"; // typescript error (quoted below)
}
类型 '"banana"' 不可分配给类型 'T[{ [Key in keyof T]: T[Key] extends string ? 关键:从不;}[keyof T]]'。ts(2322)
据我了解,任何字符串都应该可以分配给obj[key]
因为string extends obj[key]
是真的。
我只是想知道这是否是我的语法或对类型系统的理解的一些错误,或者它是否是 TypeScript 的静态类型分析的限制(或一般静态类型分析的限制)。
当然,我可以使用以下命令强制代码工作as any
:
function setProp<T>(obj: T, key: AssignableKeys<T, string>) {
obj[key] = "banana" as any; // no error
}
const myObj: IObj = { A: "", B: 5 };
setProp(myObj, "A"); // great
setProp(myObj, "B"); // error (as expected)
但我想知道为什么打字稿不喜欢原始形式的代码。
谢谢!
解决方案
推荐阅读
- arrays - 我可以在 ruby 中有一个正则表达式数组吗?
- android - SQLite getwritableDatabase 返回 null
- java - 此生产者消费者的非法监视器状态异常?
- javascript - 如何在 C# 应用程序中显示 HTML 画布?
- angular - 在 Angular 中,如何检查相对路由是否处于活动状态?
- javascript - 使用赋值解构交换术语在函数内部不起作用
- python - 当任何一个元素与另一个列表的元素匹配时,如何从列表列表中提取列表?
- javascript - 类列表如何工作?
- c# - 如何使用 xUnit 测试 ref struct 方法是否抛出异常?
- javascript - 从 JavaScript 获取 SSO 用户的 ID 或名称