Typescript 将类型缩小为具有某些属性的对象
我试图弄明白为什么typescript不喜欢下面的结构。编译器错误在代码中的注释中Typescript 将类型缩小为具有某些属性的对象,typescript,Typescript,我试图弄明白为什么typescript不喜欢下面的结构。编译器错误在代码中的注释中 const BAR = Symbol(); function foo<T>(that: T) { if (that !== null && typeof that === "object" && BAR in that) { // Element implicitly has an 'any' type because expressi
const BAR = Symbol();
function foo<T>(that: T) {
if (that !== null && typeof that === "object" && BAR in that) {
// Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type 'unknown'.
// Property '[BAR]' does not exist on type 'unknown'.ts(7053)
const bar = that[BAR];
console.log(bar);
}
}
function foo2<T>(that: T) {
if (that !== null && typeof that === "object" && "BAR" in that) {
// Element implicitly has an 'any' type because expression of type '"BAR"' can't be used to index type 'unknown'.
// Property 'BAR' does not exist on type 'unknown'.ts(7053)
const bar = that["BAR"];
console.log(bar);
}
const BAR=Symbol();
函数foo(即:T){
if(that!==null&&typeof that===“object”&&BAR in that){
//元素隐式具有“any”类型,因为“unique symbol”类型的表达式不能用于索引类型“unknown”。
//类型“未知”上不存在属性“[BAR]”。ts(7053)
常数bar=该[bar];
控制台日志(bar);
}
}
函数foo2(即:T){
if(that!==null&&typeof that===“object”&&BAR”在该字段中){
//元素隐式具有“any”类型,因为类型为“BAR”的表达式不能用于索引类型“unknown”。
//类型“未知”上不存在属性“BAR”。ts(7053)
常数条=该[“条”];
控制台日志(bar);
}
if
是否应该足够缩小类型范围?由于泛型函数没有约束,TS不知道t将是什么。因此它会抱怨。TS进行静态类型分析,而不是运行时分析。if语句不属于前一类
TypeScript的强大之处在于它的明确性,因此,如果您已经知道将传递给函数(,该函数是
)的属性具有特定的键(条
),那么您应该做出声明
如果您想坚持使用泛型,例如可以这样做:
const BAR='BAR';
接口断路器{
[酒吧]:任何,
}
函数foo(即:T){
if(that!==null&&typeof that===“object”&&BAR in that){
常数bar=该[bar];
控制台日志(bar);
}
}
/*
字符串替代项:
接口断路器{
酒吧:任何,
}
..然后是上面的字符串函数
*/
请注意,TS不允许接口将符号用作键
一些额外的想法
我不知道你在这里使用泛型的原因,但是如果你知道你将把这个函数传递给一个对象,并且你对这个函数的结构有一些了解,你也可以只使用一个接口,怎么样?这不可能是最好的解决方案,但它确实有效
const BAR=Symbol();
函数foo(即:T){
if(that!==null&&typeof that==“object”&&hasProperty(that,BAR)){
常数bar=该[bar];
控制台日志(bar);
}
}
函数foo2(即:T){
if(that!==null&&typeof that==“object”&&hasProperty(that,“BAR”)){
常数条=该[“条”];
控制台日志(bar);
}
}
函数hasProperty(obj:any,prop:P):obj是{[;in P]:unknown}{
obj中的返回道具;
}
您应该将收到的错误添加到问题中错误在comments@user3612643,我认为TS编译器在编写时不能很好地支持符号索引。@miqh编译器还抱怨foo2使用了字符串。请检查类型谓词:您的答案指向错误的方向。请考虑r“that:T | Barable”而不是“T extensed Barable”。如果“T extensed Barable”,则显然,If始终为真。您没有真正给出任何上下文,因此我假设您的If语句是为了修复错误。正如我所说的“如果您已经知道将传递给函数(该函数)的属性具有特定的键(BAR),你应该做出声明。”-如果不是的话,那显然不是。与其对我的答案投反对票并抱怨,你可以更好地描述你的问题,也许有人能给你更好的答案。看起来不错,但实际上我认为ts编译器应该自动检测到它。。。
const BAR = Symbol();
function foo<T>(that: T) {
if (that !== null && typeof that === "object" && hasProperty(that, BAR)) {
const bar = that[BAR];
console.log(bar);
}
}
function foo2<T>(that: T) {
if (that !== null && typeof that === "object" && hasProperty(that, "BAR")) {
const bar = that["BAR"];
console.log(bar);
}
}
function hasProperty<P extends keyof any>(obj: any, prop: P): obj is { [_ in P]: unknown } {
return prop in obj;
}