2017-08-13 53 views
3

介紹問題

我奮力開發編寫的打字稿特定功能強大的輸入...樂趣+挫折打字稿映射類型

爲了便於說明,可以說我在工作部汽車並且具有功能registerVehicles,其可以接受許多按名稱組織的車輛的登記細節,並返回每輛車的車牌。

interface RegistrationDetails { 
    transmission?: 'manual' | 'automatic'; 
    wheelCount?: number; 
    horsePower?: number; 
} 

const licensePlates = registerVehicles({ 
    sportsCar: { 
     transmission: 'manual', 
     wheelCount: 4, 
     horsePower: 762 
    }, 
    motorBike: { 
     transmission: 'manual', 
     wheelCount: 2 
    }, 
    hoverBoard: { 
     // All registration details are optional 
    } 
}); 

該函數返回一個對象與每輛車的名字和他們的新註冊的牌照:

expect(licensePlates).to.eql({ 
    sportsCar: 'ABCD-1234', 
    motorBike: 'SPDY-5678', 
    hoverBoard: 'BTTF-2' 
}); 

的功能存在,完美的作品,問題是得到了強類型

該解決方案必須滿足以下條件:

  1. 可變licensePlates應該從函數的結果來隱式地鍵入。

  2. 試圖通過一個不存在的註冊細節應該在編譯時出錯。

    registerVehicles({ 
        car: { 
         cowPower: 500 // <-- Spelling mistake, should be horsePower 
        } 
    }) 
    
  3. 嘗試訪問您沒有註冊應該在編譯時錯誤車輛的車牌:

    const licensePlates = registerVehicles({ 
        ferrari: { 
         horsePower: 562 
        } 
    }); 
    
    alert(licensePlates.furrari); // <-- Spelling mistake, should be ferrari 
    
  4. 打字稿應該知道每個牌照是在編譯時

    字符串
    const licensePlates = registerVehicles({ 
        ferrari: {} 
    }); 
    
    alert(licensePlates.ferrari * 5); // <-- Error, you can't multiple a string 
    

我已經得到接近,但每一個解決方案,我嘗試最終失敗到m至少滿足上述要求之一。幫助我堆棧溢出社區,你是我唯一的希望!

回答

3

實用程序類型「記錄」做你想要的。有了它,您可以將動態屬性從一種類型映射到另一種類型。 (Try it in the Playground):

function registerVehicles<K extends string>(p: Record<K, RegistrationDetails>): Record<K, string> { 
    return null; 
} 

K類型將是一個字符串文字類型例如。 "sportsCar" | "motorBike" | "hoverBoard"

更新:它沒有很好的記錄。但這裏是a link to the Documentation,我在這裏找到a example

+0

這是完美的,非常感謝你! – CodeAndCats

+0

@Magu,我很好奇你是否對https://stackoverflow.com/q/46596846/678505有一些創造性的想法,我認爲它甚至可以將TS映射類型提升到更高層次:-) –