亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

類型腳本說交集屬性不存在

類型腳本說交集屬性不存在

qq_花開花謝_0 2022-09-23 16:36:44
我有一個變量,它從一個類型開始,但是在映射了幾次之后,應該添加一個屬性,就像.但是,在倒數第四行中,打印屬性的附加項會給我一個 TS 錯誤,即使該屬性確實存在并且日志記錄的工作方式與我預期的一樣,打印三個屬性 、 和 。IPerson[]_idArray<IPerson & IWithId>_idfnamelname_id我想也許我需要以某種方式重新鑄造它,比如mapped = collection.map(mapperB) as Array<IPerson & IWithId>這不起作用,值得慶幸的是,對于imo應該已經根據函數的返回類型獲取其類型的變量,這樣做似乎非常冗長。mapperBlet _id = 0;interface IPerson {     fname: string;    lname: string;}interface IWithId {     _id: number;}function getNumber() {     return _id++}async function getData(json: string): Promise<IPerson[]> {     return JSON.parse(json)}function mapperA(entry: IPerson): IPerson {     return {        ...entry,        lname: entry.lname.toUpperCase()    }}function mapperB(entry: IPerson): IPerson & IWithId {     const _id = getNumber();    return {        ...entry,        _id    } }async function main() {    const json = `[{"fname":"john","lname":"doe"},{"fname":"jane","lname":"doe"}]`        const collection = await getData(json)    let mapped = collection.map(mapperA)    mapped = collection.map(mapperB)    console.log(mapped[0]._id); // Property '_id' does not exist on type 'IPerson'.    return mapped;}main().then(console.log)如果我使用另一個變量來保存第二個map函數的值,我可以讓它工作,即我很好奇為什么我不能使用我的原始變量?const mapped2 = collection.map(mapperB)為什么類型腳本不從顯式聲明的返回值中推斷出 的值?我可以讓它為我做這件事嗎?mappedmapperB類型腳本游樂場
查看完整描述

3 回答

?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

類型腳本從它的第一個賦值(初始化)中推斷出的類型,所以它是:mappedIPerson[]


In TypeScript, there are several places where type inference is used to provide

type information when there is no explicit type annotation. For example, in this

code


> let x = 3;


The type of the x variable is inferred to be number. This kind of inference takes place

when initializing variables and members, setting parameter default values, and 

determining function return types.

摘自TypeScript手冊中的“類型推斷”一章(我鏈接了它即將推出的2.0測試版),我建議閱讀這篇文章。


然后,第二個賦值不會擴展定義,但也沒有錯誤,因為對象可以具有其他屬性。訪問 時,您會收到一個錯誤,因為 TypeScript 無法從最初推斷的類型中確定數組條目還包含屬性。_id_id


注意:強制轉換 給 TypeScript 沒有附加信息,所以結果是一樣的。mapped = collection.map(mapperB) as Array<IPerson & IWithId>


為了便于推理類型,我個人建議將轉換后的值分配給新變量(如您使用 .并選擇富有表現力的變量名稱(權衡變得冗長,但如果你保持函數復雜性足夠小,這種情況不應該經常發生):const mapped2 = collection.map(mapperB)


const filteredList = list.filter(...);

const filteredListWithIds = filteredList.map(...)

不直接相關,但出現錯誤:返回新數組。從 的值會立即丟失,因為它映射 = 集合。在基于您的真實代碼創建游樂場示例時,也許是一個錯誤?Array.prototype.map()mappedlet mapped = collection.map(mapperA)s being overwritten at the next line during


查看完整回答
反對 回復 2022-09-23
?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

這里的問題是在以下行:


let mapped = collection.map(mapperA) // here you declare mapped with the type IPerson[]

mapped = collection.map(mapperB) // here mapped already has a type and can't be changed

console.log(mapped[0]._id); // here you try to access a property IPerson doesn't have

您可以嘗試按照其他答案鏈接映射器或僅將兩個映射器強制為一個來解決此問題:


function mapper(entry: IPerson): IPerson & IWithId {

    const _id = getNumber();


    return {

        ...entry,

        _id,

        lname: entry.lname.toUpperCase()

    }

}


// later in your main function

let mapped = collection.map(mapper); // here mapped is declared as (IPerson & IWithId)[]

console.log(mapped[0]._id); // now you can access any IWithId property

希望這有幫助。


查看完整回答
反對 回復 2022-09-23
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

是的,一旦賦值,就無法更改 typescript 中變量的類型。

如上面的示例中所述,您可以使用不同的變量。但是根據你的關注點,你只想使用一個變量,你可以通過一個接一個地鏈接它們來調用兩個映射器。

類型腳本以非常好的方式支持函數調用的鏈接。因此,您可以將最后兩行代碼替換為單行代碼,如下所示:

let mapped = collection.map(mapperA).map(mapperB)

我希望您覺得這有幫助。您可以解決您的錯誤。


查看完整回答
反對 回復 2022-09-23
  • 3 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號