代码之家  ›  专栏  ›  技术社区  ›  doberkofler

不兼容的对象类型

  •  1
  • doberkofler  · 技术社区  · 6 年前
    /* @flow */
    
    type optionsType = Array<{id: string | number, name: string}>;
    type modelsType = Array<{id: number, name: string}>;
    
    function getOptions(options: optionsType): string {
      return options.reduce((a, e) => {
        return a + `<option value="${e.id.toString()}">${e.name}</option>`;
      }, '');
    }
    
    const options: modelsType = [
      {id: 1, name: 'punto'},
      {id: 2, name: 'duo'},
      {id: 500, name: 'cinquecento'},
    ];
    console.log(getOptions(options));
    

    上面的例子抱怨 Cannot call "getOptions" with "options" bound to "options" because number [1] is incompatible with string [2] in property "id" of array element. 但据我所知 modelsType 只是比 optionsType . 为什么Flow会抱怨,我如何才能让它按预期工作?

    2 回复  |  直到 6 年前
        1
  •  2
  •   loganfsmyth    6 年前

    如果

    let second: secondType = first;
    

    如果允许的话,这就意味着这是合法的

    second.id = "some-id";
    

    但这会破坏 firstType 因为它是同一个对象,类型是 number ,但现在它被分配了一个字符串。

    要想让这一切成功,你必须这么说 secondType.id 是只读的,或者是“协变的”。你可以通过改变

    type secondType = {id: string | number, name: string};
    

    type secondType = {+id: string | number, name: string};
    

    ( Example on flow.org/try )

        2
  •  0
  •   doberkofler    6 年前

    我的用例的最终解决方案:

    /* @flow */
    
    type optionsType = $ReadOnlyArray<{+id: string | number, name: string}>;
    type modelsType = Array<{id: number, name: string}>;
    
    function getOptions(options: optionsType): string {
      return options.reduce((a, e) => {
        return a + `<option value="${e.id.toString()}">${e.name}</option>`;
      }, '');
    }
    
    const options: modelsType = [
      {id: 1, name: 'punto'},
      {id: 2, name: 'duo'},
      {id: 500, name: 'cinquecento'},
    ];
    console.log(getOptions(options));