V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
tlerbao
V2EX  ›  问与答

强行上 TS,就自寻烦恼,体会不到他们说的 TS 带来的乐趣,各种波浪线懵逼中?

  •  
  •   tlerbao · 2023-03-16 15:40:59 +08:00 · 2782 次点击
    这是一个创建于 625 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大致代码如下

    // * 请求响应参数(不包含 data)
    export interface Result {
    	code: string;
    	message: string;
    }
    
    // * 请求响应参数(包含 data)
    export interface ResultData<T = any> extends Result {
    	data: T;
    }
    
    
    // 封装的 post 请求
    post<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
    	return this.service.post(url, params, _object);
    }
    
    // 具体请求
    export const previewCode = (params: any) => {
    	return http.post(`/generate/preview`, params);
    };
    
    

    前面是基本定义,下面是使用的问题

    就根据我这种情况,在实际调用中,要如何不写成 anyscrip ,显然 const { data }:{data:any} 就不会报错了,但是规范的做法是怎样的呢?const { data }:{data:string} 又会报另一个错误:

    TS2322: Type 'ResultData<unknown>' is not assignable to type '{ data: string; }'. Types of property 'data' are incompatible.      Type 'unknown' is not assignable to type 'string'.

    const preview = async (type: any) => {
    	const { data } = await previewCode(post);
    	previewContent.value = data;
        // 波浪线,鼠标放这行会提示 TS2322: Type 'unknown' is not assignable to type 'string'.
    };
    

    到底怎么做才比较规范

    24 条回复    2023-03-17 14:36:19 +08:00
    guisheng
        1
    guisheng  
       2023-03-16 15:43:03 +08:00 via iPhone
    个人没必要用的 是真的麻烦。推荐用一些自动化生成的插件
    tlerbao
        2
    tlerbao  
    OP
       2023-03-16 15:45:33 +08:00
    @guisheng jb 家的 ide 如 webstorm 有吗?
    LLaMA2
        3
    LLaMA2  
       2023-03-16 16:02:05 +08:00
    export const previewCode = (params: any) => {
    return http.post(`/generate/preview`, params);
    };


    you need declare your return type for method post,so you'd better write your logic lolike this:



    post<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
    return new Promise((resolve) => {
    resolve({
    // here just a sample!
    code: '200',
    message: 'your message',
    data: {} as T,
    });
    });
    }

    test(): Promise<ResultData<string>> {
    const previewCode = (params: any) => {
    // be careful type for post call
    return this.post<string>(`/generate/preview`, params);
    };
    return previewCode('myParams');
    }
    EyebrowsWhite
        4
    EyebrowsWhite  
       2023-03-16 16:41:30 +08:00
    就是泛型使用问题,可以多看一些泛型代码,熟练点就好了
    shanyuhai123
        5
    shanyuhai123  
       2023-03-16 16:47:00 +08:00   ❤️ 1
    全部使用 axios.request 请求,不需要额外封装,最后定义入参和返回值即可
    cyrbuzz
        6
    cyrbuzz  
       2023-03-16 16:55:56 +08:00
    封装 axios 看看我这篇?个人用着还不错。

    https://juejin.cn/post/7096372659079872526#heading-11

    类型体操刷一刷 TypeScript 挑战基本业务应该没什么可以难倒的。

    https://juejin.cn/post/7206208345605849149
    panlatent
        7
    panlatent  
       2023-03-16 16:56:03 +08:00 via iPhone
    我觉得对于有其他现代强类型语言经验的开发者,比如 C# ,Swift ,TS 是比 JS 更好上手的选择
    zhy0216
        8
    zhy0216  
       2023-03-16 17:00:00 +08:00
    enchilada2020
        9
    enchilada2020  
       2023-03-16 17:02:24 +08:00 via Android
    @zhy0216 😆
    yuuko
        10
    yuuko  
       2023-03-16 17:08:05 +08:00   ❤️ 1
    因为你 `this.service.post` 返回 `Promise<unknow>`,所以肯定报错。可以确定下 data 的类型 `T extends unknown ? any : T` 确保 data 不会是 unknow
    FightPig
        11
    FightPig  
       2023-03-16 17:09:48 +08:00
    我个人项目用过几次后又用回 js 了,人多倒是可以
    Chad0000
        12
    Chad0000  
       2023-03-16 17:14:11 +08:00
    @FightPig
    看你是什么类型的程序员,我是从后端发展的全端,前端主要是 Angular 。对于后端来说 TS 就是天然的,还有 Angular 的依赖注入等知识。我个人项目也用,好处就是写了很久的逻辑回头改也不需要文档,一切有类型约束在。
    ruoxie
        13
    ruoxie  
       2023-03-16 20:11:35 +08:00
    // #region 机构-公司主体详情
    export interface IFetchCompanySubjectDetailResult {
    /**
    * 状态码:0 成功
    */
    code: number;
    /**
    * 状态描述
    */
    message: string;
    data?: {
    /**
    * ID
    */
    id: number;
    /**
    * 所属机构 ID
    */
    distributors_id: number;
    /**
    * 公司名称
    */
    company_name: string;
    /**
    * 公司地址
    */
    company_address: string;
    /**
    * 公司电话
    */
    company_phone: string;
    /**
    * 公司统一社会信用代码
    */
    company_idcard: string;
    /**
    * 收款方名称
    */
    receive_name: string;
    /**
    * 收款方开户行
    */
    receive_bank: string;
    /**
    * 收款方账号
    */
    receive_account: string;
    /**
    * 账户信息
    */
    user_account: string;
    /**
    * 是否删除
    */
    if_deleted?: string;
    /**
    * 法定代表人
    */
    legal_representative?: string;
    /**
    * 允许类型:0 不允许,1 允许
    */
    is_allow?: number;
    /**
    * 创建时修
    */
    created_at?: string;
    /**
    * 最后修改时间
    */
    updated_at?: string;
    };
    }

    export interface IFetchCompanySubjectDetailData {
    /**
    * 所属机构 ID */
    distributors_id: number;
    }

    /**
    * 机构-公司主体详情
    * xxxxx/project/2523/interface/api/193535
    * @author xxxxx
    *
    * @param {IFetchCompanySubjectDetailData} data
    * @returns
    */
    export function fetchCompanySubjectDetail(data: IFetchCompanySubjectDetailData) {
    return request<IFetchCompanySubjectDetailResult>(`z_contract_companies/show`, {
    method: 'POST',
    data,
    });
    }
    // #endregion

    工具生成的,项目禁止使用 any 。
    ruoxie
        14
    ruoxie  
       2023-03-16 20:13:32 +08:00
    export interface ResultData<T = any> extends Result {
    data: T;
    }
    把 any 改成 unknown , 不写具体类型直接报错,代码提交或者构建的时候跑一遍 tsc check
    ruoxie
        15
    ruoxie  
       2023-03-16 20:19:58 +08:00
    开发阶段加个 checker 插件,接口字段改了或者组件字段改了,用的地方没改的话直接报错,改起来不要太方便
    chenzhe
        16
    chenzhe  
       2023-03-16 20:25:19 +08:00
    export type BaseResult<T> = {
    code: number;
    msg: string;
    data: T;
    }

    export type UserInfo = {
    id: string;
    name: string;
    avatar: string;
    phone: string;
    }

    export type LoginResult = BaseResult<UserInfo>

    const { data: { code, msg, data: userInfo } } = await axios.post<LoginResult>("/api/login", {
    username: "testuser",
    password: "testpassword"
    })
    siknet
        17
    siknet  
       2023-03-16 20:37:20 +08:00
    我以为是.....真的 TS

    还要强上

    告辞
    UnknownDomain
        18
    UnknownDomain  
       2023-03-17 01:01:44 +08:00 via Android
    @siknet ? 你不对劲
    noreplay
        19
    noreplay  
       2023-03-17 07:13:23 +08:00 via Android
    @siknet 你不对劲?
    guiyun
        20
    guiyun  
       2023-03-17 08:51:49 +08:00
    @Chad0000 这东西看框架吧,angular 的 ts 我写的挺舒服的,但 vue 的写的想死
    wyl986
        21
    wyl986  
       2023-03-17 08:59:52 +08:00   ❤️ 1
    用 ts 写,一个是你很久之后再来维护很有信心,即使没有充分的单元测试,你也知道写的是个什么东西,二是代码提示会好很多,三个是确实能在写的时候找到一些 js 不容易找到的问题。习惯了 ts 之后确实更喜欢用 ts 一些,虽然刚开始确实各种波浪线,还要写得比 js 多多了

    ps:尽可能不要用 any ,any 一般是用在那种 js 写的第三方包上面,而不是你自己的代码上面
    duan602728596
        22
    duan602728596  
       2023-03-17 13:52:55 +08:00
    interface Result {
    code: string;
    message: string;
    }


    interface ResultData<T = unknown> extends Result {
    data: T;
    }

    function post<T>(url: string, params?: Record<string, any>, _object = {}): Promise<ResultData<T>> {
    return this.service.post(url, params, _object);
    }

    const previewCode = (params: any): Promise<ResultData<string>> => {
    return post<string>(`/generate/preview`, params);
    };

    const preview = async (type: any) => {
    const { data }: { data: string } = await previewCode(post);
    let previewContent;
    previewContent.value = data;
    };

    稍微改了一下
    PrtScScrLk
        23
    PrtScScrLk  
       2023-03-17 14:12:11 +08:00
    @siknet 所以是什么 TS ,我想知道!
    siknet
        24
    siknet  
       2023-03-17 14:36:19 +08:00
    @PrtScScrLk #23 “TS” 可以指“transsexual”的缩写,而“transsexual”则是指性别认同障碍( Gender Identity Disorder ,GID )的一种,这是指一个人认为自己的生理性别与其内心认同的性别不符,并希望通过医疗手段改变生理性别。但是,这个术语已经被逐渐取代,现在更常用的是“性别确认”( gender affirmation )或“性别变异”( gender variance )。


    俗称:变性人
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2650 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 04:01 · PVG 12:01 · LAX 20:01 · JFK 23:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.