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

与对象相交时字符串文本与字符串类型不兼容

  •  1
  • Tieme  · 技术社区  · 8 年前

    按预期工作:

    // @flow
    
    type FontName = string
    const doSomethingWithFontName = (fontName: FontName) => console.log(fontName)
    
    type StrictFontName = 'Arial' | 'Verdana' | 'Times'
    const doSomethingWithStrictFontName = (fontName: StrictFontName) => doSomethingWithFontName(fontName)
    
    doSomethingWithStrictFontName('Times')
    

    打电话 doSomethingWithFontName doSomethingWithStrictFontName StrictFontName 只包含字符串,因此我可以调用 多索梅辛维方名称 严格字体名

    // @flow
    
    type Typography = { 
      fontName?: string; 
    }
    const doSomethingWithTypography = (typography: Typography) => console.log(typography)
    
    type StrictTypography = Typography & { 
      fontName?: 'Arial' | 'Verdana' | 'Times'; 
    }
    const doSomethingWithStrictTypography = (typography: StrictTypography) => {
      doSomethingWithTypography(typography)
    }
    
    doSomethingWithStrictTypography({fontName: 'Times'})
    

    我只是把我们的严格对象转发给一个更宽松的函数,为什么这不起作用?流可以分辨 StrictTypography fontName 还是一根绳子对吗?

    thread 并提出将超级类型作为一个解决方案作为一个接口:

    // @flow
    
    // Interface instead of type
    interface Styles { 
      fontName?: string; 
    }
    
    const doSomethingWithStyling = (styles: Styles) => console.log(styles)
    
    type StrictStyles  = Styles & { 
      fontName?: 'Arial' | 'Verdana' | 'Times'; 
    }
    const doSomethingWithStrictStyling = (styles: StrictStyles) => {
      doSomethingWithStyling(styles)
    }
    
    doSomethingWithStrictStyling({fontName: 'Times'})
    

    这似乎可行,但我不确定这是否是正确的方法。如果我导入这个接口,我会得到一个 Use of future reserved word in strict mode ...

    here

    1 回复  |  直到 8 年前
        1
  •  2
  •   EugeneZ    8 年前

    这里发生了两件事。

    通过定义交叉点 Styles & { fontName?: 'Arial' | 'Verdana' | 'Times' } fontName 一定是那种 string 'Verdana' 或者什么,那么它也不可能 任何其他 一串

    在第一个例子中,它之所以有效是因为 variance . 基本上,第一个更广泛的函数接受 一串 反变体 并允许不太特定的类型,例如 'foo' 'bar' ,是的, '凡尔达纳' . Flow自动将函数参数类型解释为逆变,将函数返回类型解释为协变。

    所以你的目的可能是:

    type StrictTypography = { 
      fontName?: 'Arial' | 'Verdana' | 'Times'; 
    }
    

    但它仍然不起作用,因为尽管参数是相反的,但对象属性 ,所以现在它只满足于 而且很宽 一串 + 符号:

    type Typography = {
      +fontName?: string; 
    }
    

    Completed example.