為什么Typescript類不“知道”它自己的屬性?

我們想在超類上創建一個泛型方法,該方法接受一個參數,該參數是子類上某一類型的任何屬性的名稱。考慮一下這個(非常做作的)例子:

class CanUpcase {
    upcase<PropertyName extends keyof this>(
        propertyName: this[PropertyName] extends string ? PropertyName : never
    ) {
        return this[propertyName].toUpperCase(); // Property 'toUpperCase' does not exist on type 'this[this[PropertyName] extends string ? PropertyName : never]'.
    }
}

class User extends CanUpcase {
    age = NaN;

    name = ``;

    constructor() {
        super();

        this.upcase('name'); // Argument of type '"name"' is not assignable to parameter of type 'this["name"] extends string ? "name" : never'.ts(2345)
    }
}

const user = new User();
user.upcase('name'); // No error

我們預期upcase會接受'name',因為'name'屬性是一個字符串。

然而,當user.upcase('name')按預期工作時,this.upcase('name')拋出了一個錯誤,如圖所示。

此外,在upcase內,this[propertyName]不被識別為字符串。

  1. 為什么this.upcase拋出錯誤而不是user.upcase
  2. 為什么this[propertyName]不被識別為字符串?

Thanks!

? 最佳回答:
  1. 這個問題源于這樣一個事實,即TypeScript不會像對具體實例(用戶)那樣在類內縮小范圍。
  2. 發生這種情況是因為TypeScript在方法中沒有正確跟蹤propertyName和此[propertyName]之間的關系。

關鍵問題在于這條線:

return this[propertyName].toUpperCase();

盡管我們將propertyName限制為僅包含[propertyName]為字符串的鍵,但TypeScript不會將此約束應用于此[propertyName]的解析類型。這是由于使用條件類型時TypeScript的類型推理限制造成的。

解決方案:使用顯式泛型約束

class CanUpcase {
    upcase<K extends keyof this & string>(propertyName: this[K] extends string ? K : never) {
        return (this[propertyName] as unknown as string).toUpperCase();
    }
}

主站蜘蛛池模板: 久久久人妻精品无码一区| 亚洲国产一区在线| 蜜桃无码一区二区三区| 亚洲日韩精品一区二区三区无码| 一区二区三区在线观看视频 | 国产人妖在线观看一区二区| 无码一区二区三区免费视频| 日韩一区二区三区免费体验| 一区二区日韩国产精品| 亚洲中文字幕无码一区二区三区| 国产精品女同一区二区| 久久4k岛国高清一区二区| 亚洲福利视频一区二区三区| 日本一区二区三区爆乳| 精品视频在线观看一区二区| V一区无码内射国产| 91福利国产在线观一区二区| 国模无码视频一区二区三区| 国产精品男男视频一区二区三区| 少妇精品久久久一区二区三区| 国产精品视频一区麻豆| 三级韩国一区久久二区综合| 久久精品国产免费一区| 日韩成人无码一区二区三区| 丰满人妻一区二区三区免费视频 | 老熟妇高潮一区二区三区| 内射一区二区精品视频在线观看| 中文字幕一区二区三区四区| 精品国产鲁一鲁一区二区| 无码精品前田一区二区| 久久免费精品一区二区| 国产精品成人一区二区三区| 日韩一区二区电影| 日韩视频在线一区| 亚洲国产一区二区三区青草影视| 日本精品一区二区三区在线视频| 久久亚洲日韩精品一区二区三区| 一区二区三区免费在线视频| 亚洲一区二区三区乱码在线欧洲| 国产精品成人国产乱一区| 亚洲AV香蕉一区区二区三区 |