2017-12-28 27 views
1

material-ui에 대한 테마를 만들 때 두 가지 새로운 팔레트 옵션을 추가했습니다.이 옵션을 사용하면 밝은 영역과 어두운 영역을 더 잘 나타낼 수 있습니다. 나는 도우미에게 렌더링 WithStyles에 다음과 같은 추가 옵션을 사용하려고 할 때 문제가 발생이material-ui @ next와 typescript로 테마 확장하기

import {Theme} from "material-ui/styles"; 
import {Palette} from "material-ui/styles/createPalette"; 

export interface ExtendedTheme extends Theme { 
    palette: ExtendedPalette 
} 

export interface ExtendedPalette extends Palette { 
    light: Color, 
    dark: Color, 
} 

을 나타 내기 위해 Theme 유형을 확장 한 기능적으로 내 코드는 순수 자바 스크립트에서 잘 작동

const styles = (theme : ExtendedTheme) => ({ root: {color: theme.light['100'] }}); 

export interface MyProps {classes: {[index: string] : string}}; 
const MyComponent = (props : MyProps) => {...}; 

// Type ExtendedTheme is not assignable to Theme 
export default withStyles(styles : StyleRulesCallback)(MyComponent); 

하지만 이후 유형이 다르면 오류가 발생합니다. 내가 Theme

답변

0
을 구현하는 것이 ExtendedTheme 있도록 인터페이스를 연장 다형성 방식으로 작동 것이라고 생각

export type StyleRulesCallback<ClassKey extends string = string> = (theme: Theme) => StyleRules<ClassKey>; 

: 재료 UI의 typings는 Theme의 유형이 스타일 콜백 함수의 유일한 인수 될 것으로 기대

내가 함께 왔어요 유일한 대답은 너무 내 스타일 그리고

export interface ExtendedPalette extends Palette { 
    light?: Color, 
    dark?: Color, 
} 

나는 이러한 옵션이 종류는의 인 존재하는지 확인해야 콜백처럼 내 사용자 지정 옵션을 선택하는 것입니다 번거 로움,하지만 난 다른 해결 방법은 없다고 생각

const styles = (theme : ExtendedTheme) => { 
    let light = theme.palette.light[100]; 
    if(light === undefined) light = theme.common.white; 
    { root: {color: light }} 
}; 

내가 withStyles를 사용하지만이 콜백에 대한 typings들이 있기 때문에 Theme 유형을 사용하는 경우 그 이유는 테마 객체가 콜백에 전달되는 것입니다 내 ExtendedTheme 유형에 대해 알 수있는 방법이 없습니다. ExtendedTheme에는 Theme에 대해 아무것도 모르는 옵션이 있어야 할 때 충돌이 발생합니다. 이러한 추가 옵션을 선택하여 Theme은 여전히 ​​ExtendedTheme을 준수 할 수 있습니다. 기본적으로 확장 인터페이스는 부모가 예상되는 곳에 전달 될 수 있지만 확장 인터페이스가 확장 인터페이스가 예상되는 곳에 전달 될 수 없습니다. 확장 인터페이스가 부모가 계속 준수 할 수있는 방식으로 확장되지 않는 한.

더 간단한 예는 유익한 예입니다.

export interface Foo {foo: string}; 
export interface Bar extends Foo {bar: string} 

function getFoo(f : Foo) {console.log(f.foo)} 
function getBar(b : Bar) {console.log(b.bar)} 
function getFooBar(fb: Bar) {console.log(fb.foo, fb.bar)} 

const f : Foo = {foo: 'foo'} 
const b : Bar = {foo: 'foo', bar: 'bar'} 

getFoo(f) // foo 
getFoo(b) // foo 
getBar(f) // Error Incompatible Type 
getBar(b) // bar 
getFooBar(f) // Error Incompatible Type 
getFooBar(b) // foo bar 

getFoo(b) 작품 Bar 때문에 Foo가있다 적어도 모든이 보장됩니다. getBar(f)getFooBar(f) 모두 컴파일러는 같은 Bar을 재정의함으로써 유형 Foobar

가 발생하지 않는 것을 볼 수 있기 때문에

export interface Bar extends Foo {bar? : string} 

컴파일러는 이제 푸가 Bar 유형에 대한 최소한의 자격과 일치하는지 알고 실패 하지만 암시 적 null을 확인해야합니다. 그래서이

getBar(f) 

을 작동하지만 f.bar이 정의되어 있기 때문에 컴파일러는, 좋은 암시 널 (null)에 대해 소리 것입니다. 따라서 함수를 재정의해야합니다.

function getBar(b : Bar) { 
    let bar = b.bar 
    if(bar === undefined) bar = b.foo; 
    console.log(bar); 
} 

getBar(b) // bar 
getBar(f) // foo