2016-12-25 234 views
0

我有一个类型转换对象插入到类型

export type LocationQuery = { 
    showWarnings: boolean; 
    showErrors: boolean; 
    startDate: string; 
    endDate: string; 
    quickDate: number; 
} 

现在,我想location.query转换从history模块将被转换成这种类型。

这样做的不便方式是手动:

let query: LocationQuery; 
query.showWarnings = location.query['showWarnings']; 
query.showErrors = location.query['showErrors']; 
... 

但有一个更方便,一个衬垫的方法?裸记住location.query可能有,我不会关心其他领域(所以如果有location.query['someOtherField'],不应该进入query

+0

什么是有问题的历史模块? – pvg

+0

你试过简单的铸造吗? '让查询︰LocationQuery = location.query;' –

+1

@SenJacob这将包括'someOtherField'和Koshua不希望它在LocationQuery – Dan

回答

0

有太多的方法可以做到这一点。
这可能是他们中的一个

import * as assert from "assert"; 

/** 
* will copy all blueprint.keys from source 
* or default to blueprint (default) value; 
* @returns a copy of blueprint with source values 
*/ 
const copy = <TSource extends {}, TTarget extends {}> 
    (source: TSource, bluePrint: TTarget): TTarget => { 
    let result: any = {}; 
    // see: Object.getOwnPropertyNames, its shallow 
    for (let key of Object.getOwnPropertyNames(bluePrint)) { 
     result[key] = source.hasOwnProperty(key) 
      ? source[key] 
      // default to blueprint prop, will be undefined 
      // but they key will exists 
      : bluePrint[key]; 
    } 
    return result; 
} 

export type LocationQuery = { 
    showWarnings: boolean; 
    showErrors: boolean; 
    startDate: string; 
    endDate: string; 
    quickDate: number; 
} 

interface History { 
    showWarnings: boolean; 
    showErrors: boolean; 
    startDate: string; 
    endDate: string; 
    quickDate: number; 
    somethingElse: any; 
} 

/** 
* Default Value, blueprint, skeleton, shape,etc 
*/ 
const empty: LocationQuery = { 
    showWarnings: undefined, 
    showErrors: undefined, 
    startDate: undefined, 
    endDate: undefined, 
    quickDate: undefined, 
}; 

/** 
* test's source subject 
*/ 
const history: History = { 
    showWarnings: false, 
    showErrors: false, 
    startDate: '2016-12-01', 
    endDate: '2016-12-31', 
    quickDate: 1, 
    somethingElse: false 
} 

/** 
* LocationQuery it's 'Partial'History 
*/ 
const expected: LocationQuery = { 
    showWarnings: false, 
    showErrors: false, 
    startDate: '2016-12-01', 
    endDate: '2016-12-31', 
    quickDate: 1, 
} 


describe("copy",() => { 

    it("shallow copy, all desired members",() => { 
     let result = copy(history, empty); 
     assert.deepEqual(expected, result); 
     // All Key Present? 
     // somethingElse shoudl be missing... 
     assert.equal(
      "showWarnings, showErrors, startDate, endDate, quickDate", 
     Object.keys(result).reduce((a,b)=> a+ ", "+b)); 
    }); 

    it("shallow copy, all desired members and defaults to missing props",() => { 

     // doesn't provide all memebers 
     const historyLike = { 
      showWarnings: true, 
      showErrors: true, 
     } 

     let result = copy(historyLike, empty); 

     const expected_result_with_defaults = { 
      showWarnings: true, 
      showErrors: true, 
      startDate: undefined, 
      endDate: undefined, 
      quickDate: undefined, 
     }; 

     // Values Ok? 
     assert.deepEqual(expected_result_with_defaults, result); 

     // All Key Present? 
     assert.equal(
      "showWarnings, showErrors, startDate, endDate, quickDate", 
      Object.keys(result).reduce((a,b)=> a+ ", "+b) 
     ) 
    }); 
}) 

另一个用于打字稿2.1+

/** 
* Requires Typescript 2.1 up 
* copy specified key from derived type 
* where TSource is superset of TResult 
*/ 
const copy = <TSource extends TResult, TResult extends {}>(source: {}, ...keys: (keyof TResult)[]): TResult => {  
    let result: any = {}; 
    for(let key of keys){   
     result[key] = source.hasOwnProperty(key) ? (<any>source)[key] : null; 
    } 
    return result 
} 


describe("copy",() => { 
    it("copy specified members ",() => { 
     let result = copy<History, LocationQuery>(
     /*from*/ history, 
     "showWarnings" , 
     "showErrors", 
     "startDate", 
     "endDate", 
     "quickDate"); 
     assert.deepEqual(expected, result); 
     assert.equal(
      "showWarnings, showErrors, startDate, endDate, quickDate", 
      Object.keys(result).reduce((a,b)=> a+ ", "+b) 
     )   
    }); 
}) 
0

字段名的列表:

function toLocationQuery(source) { 
    const fields = ['showWarnings', 'showErrors', 'startDate', 'endDate', 'quickDate'] 
    let res = {} 
    for (let k of fields) { 
     if (source[k] === undefined) 
      throw new Error(`Missing field "${k}"`) 
     res[k] = source[k] 
    } 
    return res as LocationQuery 
} 

let query = toLocationQuery(location.query) 

或者相同的代码,但没有重新声明的字段列表为每个呼叫:

const toLocationQuery = (function() { 
    const fields = ['showWarnings', 'showErrors', 'startDate', 'endDate', 'quickDate'] 
    return function (source) { 
     let res = {} 
     for (let k of fields) { 
      if (source[k] === undefined) 
       throw new Error(`Missing field "${k}"`) 
      res[k] = source[k] 
     } 
     return res as LocationQuery 
    } 
})() 

let query = toLocationQuery(location.query) 
相关问题