具有类型约束的通用接口接受默认类型

时间:2018-07-29 03:29:26

标签: typescript generics

我已经在打字稿中创建了一个简单的通用接口

App\Model\Entity\User Object
(
    [[new]] => 1
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => 
)

我有一个实现上述接口的简单类

interface DateAdapter<T> {
  clone(): T;
}

然后我有一个通用的class StandardDateAdapter implements DateAdapter<StandardDateAdapter> { clone: () => StandardDateAdapter; } 接口,该接口接受扩展Options的类型。默认情况下,我希望type参数为DateAdapter,所以我将其设置为:

StandardDateAdapter

不幸的是,打字稿不喜欢这样,并且抛出了错误

interface Options<T extends DateAdapter<T> = StandardDateAdapter> {
  until?: T;
}

有什么想法可以解决这个问题吗?这是错误吗?谢谢!

注意:Type 'StandardDateAdapter' does not satisfy the constraint 'DateAdapter<T>'. Types of property 'clone' are incompatible. Type '() => StandardDateAdapter' is not assignable to type '() => T'. Type 'StandardDateAdapter' is not assignable to type 'T'. 仅是通用的,因为我希望DateAdapter的返回类型等于实现clone()的类的类型。我最初在DateAdapter中尝试过DateAdapter,但是打字稿足够聪明,可以意识到StandardDateAdapter#clone()返回clone(): this;!== new StandardDateAdapter

1 个答案:

答案 0 :(得分:2)

就像当T为其默认值时TypeScript检查约束是否满足时,它不够聪明,无法用默认值替换约束中interface Options<T extends DateAdapter<T> = StandardDateAdapter & DateAdapter<T>> { until?: T; } 的出现。海事组织,这是合理的事,让TypeScript团队决定如何处理。我进行了搜索,直到2018-07-28都没有发现现有问题。

这是我能找到的最佳解决方法:

StandardDateAdapter & DateAdapter<{}>

然后默认的有效值为StandardDateAdapter,它看起来很丑,但是可​​以与 import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; window.navigator.userAgent = 'react-native'; import io from 'socket.io-client/dist/socket.io'; export default class App extends React.Component { state = { name: 'bob' } constructor(){ super(); this.socket = io('localhost:3000',{jsonp: false}); console.log('socket = ',this.socket); this.socket.on('update', () => this.setState({name: 'Nate'})); } render() { return ( <View style={styles.container}> <Text>{this.state.name}</Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, }); 进行分配,因此希望它可以满足您的所有需求。