Dva: Des doutes sur l'écriture des modèles après intégration de TypeScript

Créé le 6 juin 2019  ·  10Commentaires  ·  Source: dvajs/dva

Ce qui se produit?


Lorsque nous utilisons dva dans un projet tapuscrit, comment pouvons-nous écrire l'effet dans les modèles pour qu'il soit aussi élégant et standard que possible ? Par exemple, il y a un userModel.ts, l'effet à l'intérieur est :

*login({ payload, callback }, { put }) {
            // code here...
 },

Si notre projet utilise le plug-in eslint, à ce moment, nous obtiendrons un message d'erreur, 绑定元素“payload”隐式具有“any”类型。ts(7031) , car nous n'avons pas de type de référence, alors comment écrivons-nous le type de référence du paramètre pertinent ici ? Nous ne pouvons pas déterminer le contenu de la charge utile. Donc, actuellement, vous ne pouvez en utiliser qu'un, c'est-à-dire :

*login({ payload, callback } : any, { put }:any) {
            // code here...
 },

Y a-t-il une meilleure façon de l'écrire? Merci!

Le plus petit entrepôt reproductible

Veuillez utiliser yarn create umi créer, sélectionnez app , puis sélectionnez dva et téléchargez sur votre référentiel GitHub


rien

Étapes à reproduire, journal des erreurs et configuration associée



rien

Informations environnementales connexes

  • Version Umi : non utilisée
  • Version du nœud : 11.2.0
  • Système d'exploitation : macOS 10.14.5

Commentaire le plus utile

Merci à tout le monde à l'étage pour la recommandation, mais en tant que débutant, je veux toujours essayer mes propres mains. Après ma pratique ultérieure, j'ai découvert qu'il était possible d'extraire le modèle dva de ma solution précédente, puis de coopérer avec l'assertion. Le seul problème est qu'après la mise à niveau de Redux vers V4, son ReducersMapObject a été modifié.

/* eslint-disable no-unused-vars */
import { ReducersMapObject, Reducer, Dispatch, AnyAction, Action } from 'redux';

export interface EffectsCommandMap {
    put: <A extends Action>(action: A) => any;
    call: Function;
    select: Function;
    take: Function;
    cancel: Function;
    [key: string]: any;
}
// export type ActionWithPayload = { action: Action; payload: any; callback: Function };
export type Effect = (action: AnyAction, effects: EffectsCommandMap) => void;
export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
export type EffectWithType = [Effect, { type: EffectType }];
export interface EffectsMapObject {
    [key: string]: Effect | EffectWithType;
}

export interface ReducerEnhancer {
    (reducer: Reducer<any>): void;
}

// 使用redux-v4.x的ReducerMapObject会导致dva reducer中的action payload等参数无法确定类型(dva中使用的是3.x的redux)
// 这里从redux v3.x中找到了对应的ReducersMapObject以解决上述问题
export interface ReduxV3ReducersMapObject {
    [key: string]: Reducer<any>;
}

export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];

export interface SubscriptionAPI {
    dispatch: Dispatch<any>;
}
export type Subscription = (api: SubscriptionAPI, done: Function) => void;
export interface SubscriptionsMapObject {
    [key: string]: Subscription;
}

export default interface Model {
    namespace: string;
    state?: any;
    // reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
    reducers?: ReduxV3ReducersMapObject | ReducersMapObjectWithEnhancer;
    effects?: EffectsMapObject;
    subscriptions?: SubscriptionsMapObject;
}

Tous les 10 commentaires

Je ne sais pas si je peux obtenir l'effet que vous voulez

import { Model } from 'dva';

export default {
  name: 'test',
  state: {},
  effects: {},
} as Model;

Ce qui se produit?

Lorsque nous utilisons dva dans un projet tapuscrit, comment pouvons-nous écrire l'effet dans les modèles pour qu'il soit aussi élégant et standard que possible ? Par exemple, il y a un userModel.ts, l'effet à l'intérieur est :

*login({ payload, callback }, { put }) {
            // code here...
 },

Si notre projet utilise le plug-in eslint, à ce moment, nous obtiendrons un message d'erreur, 绑定元素“payload”隐式具有“any”类型。ts(7031) , car nous n'avons pas de type de référence, alors comment écrivons-nous le type de référence du paramètre pertinent ici ? Nous ne pouvons pas déterminer le contenu de la charge utile. Donc, actuellement, vous ne pouvez en utiliser qu'un, c'est-à-dire :

*login({ payload, callback } : any, { put }:any) {
            // code here...
 },

Y a-t-il une meilleure façon de l'écrire? Merci!

Le plus petit entrepôt reproductible

Veuillez utiliser yarn create umi créer, sélectionnez app , puis sélectionnez dva et téléchargez sur votre référentiel GitHub

rien

Étapes à reproduire, journal des erreurs et configuration associée

rien

Informations environnementales connexes

  • Version Umi : non utilisée
  • Version du nœud : 11.2.0
  • Système d'exploitation : macOS 10.14.5

Vous pouvez essayer la bibliothèque que j'ai écrite

https://github.com/DiamondYuan/dva-model-creator

Il peut être fait que chaque action et chaque type de modèle soient complets. Et il est entièrement compatible avec les dva existants.
Je l'ai utilisé dans un environnement de production.

adresse de démonstration

https://github.com/umijs/umi-examples/tree/master/typescript

https://github.com/DiamondYuan/vanaheim

@jinyang1994 J'ai utilisé dva. Que dois-je faire ?

import { Model } from 'dva';

Je veux savoir quel est le but de ceci en tant que modèle? Merci.

tout comme l'assertion de type

Si dva-core ne fonctionne pas, vous ne pouvez utiliser que le type dva

@jinyang1994
J'ai extrait un Model.ts du fichier de déclaration dva index.d.ts et certains problèmes connexes dans le problème comme référence, et je l'ai utilisé dans les modèles comme suit :

/* eslint-disable no-unused-vars */
import { ReducersMapObject, Reducer, Dispatch, AnyAction, Action } from 'redux';

export interface EffectsCommandMap {
    put: <A extends Action>(action: A) => any;
    call: Function;
    select: Function;
    take: Function;
    cancel: Function;
    [key: string]: any;
}
export interface EffectsMapObject {
    [key: string]: Effect | EffectWithType;
}
export interface ReducerEnhancer {
    (reducer: Reducer<any>): void;
    [key: string]: Reducer;
}
export interface SubscriptionAPI {
    dispatch: Dispatch<any>;
}
// export type ActionWithPayload = { action: Action; payload: any };
export type Effect = (action: AnyAction, effects: EffectsCommandMap) => void;
export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
export type EffectWithType = [Effect, { type: EffectType }];

export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];
export type Subscription = (api: SubscriptionAPI, done: Function) => void;
export interface SubscriptionsMapObject {
    [key: string]: Subscription;
}
export default interface Model {
    namespace: string;
    state?: any;
    reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
    effects?: EffectsMapObject;
    subscriptions?: SubscriptionsMapObject;
}

Avec l'assertion (en tant que modèle), les types pertinents dans les effets sont désormais correctement analysés, mais le paramètre de charge utile passé dans les réducteurs ne peut toujours pas être analysé et l'éditeur vscode signale une erreur : tapez "Action"L'attribut "payload" n'existe pas sur "

import Model from '@/utils/dva/Model';

export default {
    namespace: 'userModel',

    state: {
        status: 'logout',
        currentUser: '',
    },

    effects: {
        *login({ payload, callback }, { put }) {
            // ...
        },
    },
    reducers: {
        //这里的payload类型判断失败,报错为类型“Action<any>”上不存在属性“payload”。
        changeLoginStatus(state, { payload }) {  
            return {
                ...state,
                // ....
            };
        },
    },
} as Model;

Puis-je demander où y a-t-il un problème ? Merci!

Ce framework redux prend parfaitement en charge ts, avec des astuces de code à 100% : redux-model-ts

Merci à tout le monde à l'étage pour la recommandation, mais en tant que débutant, je veux toujours essayer mes propres mains. Après ma pratique ultérieure, j'ai découvert qu'il était possible d'extraire le modèle dva de ma solution précédente, puis de coopérer avec l'assertion. Le seul problème est qu'après la mise à niveau de Redux vers V4, son ReducersMapObject a été modifié.

/* eslint-disable no-unused-vars */
import { ReducersMapObject, Reducer, Dispatch, AnyAction, Action } from 'redux';

export interface EffectsCommandMap {
    put: <A extends Action>(action: A) => any;
    call: Function;
    select: Function;
    take: Function;
    cancel: Function;
    [key: string]: any;
}
// export type ActionWithPayload = { action: Action; payload: any; callback: Function };
export type Effect = (action: AnyAction, effects: EffectsCommandMap) => void;
export type EffectType = 'takeEvery' | 'takeLatest' | 'watcher' | 'throttle';
export type EffectWithType = [Effect, { type: EffectType }];
export interface EffectsMapObject {
    [key: string]: Effect | EffectWithType;
}

export interface ReducerEnhancer {
    (reducer: Reducer<any>): void;
}

// 使用redux-v4.x的ReducerMapObject会导致dva reducer中的action payload等参数无法确定类型(dva中使用的是3.x的redux)
// 这里从redux v3.x中找到了对应的ReducersMapObject以解决上述问题
export interface ReduxV3ReducersMapObject {
    [key: string]: Reducer<any>;
}

export type ReducersMapObjectWithEnhancer = [ReducersMapObject, ReducerEnhancer];

export interface SubscriptionAPI {
    dispatch: Dispatch<any>;
}
export type Subscription = (api: SubscriptionAPI, done: Function) => void;
export interface SubscriptionsMapObject {
    [key: string]: Subscription;
}

export default interface Model {
    namespace: string;
    state?: any;
    // reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer;
    reducers?: ReduxV3ReducersMapObject | ReducersMapObjectWithEnhancer;
    effects?: EffectsMapObject;
    subscriptions?: SubscriptionsMapObject;
}

Merci mon frère, je suis aussi débutant en ts, et j'ai beaucoup appris

Cette page vous a été utile?
0 / 5 - 0 notes