typescript 达人乱入 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wjx0912
V2EX    TypeScript

typescript 达人乱入

  •  
  •   wjx0912 205 天前 2709 次点击
    这是一个创建于 205 天前的主题,其中的信息可能已经有所发展或是发生改变。

    (1)编译错误

    let xxx: string xxx?.length 

    (2)编译正常

    let xxx: string | undefined xxx?.length 

    第二个代码仍然只是定义了一个类型,并没有赋值。 有没有人能通俗易懂的说下?从编译器的角度理解

    12 条回复    2025-03-19 08:48:30 +08:00
    twig
        1
    twig  
       205 天前
    我的理解是:第一种情况 xxx 在编译器看来不存在「空」或「未定义」的可能,所以加问号是多此一举?
    Chingim
        2
    Chingim  
       205 天前
    let xxx: string 把 xxx 声明为字符串但是又没赋值, 所以报错.

    let xxx: string | undefined 允许 xxx 是未赋值, 所以不报错
    jamesjammy061
        3
    jamesjammy061  
       205 天前
    感觉是第一行报错的
    ns09005264
        4
    ns09005264  
       205 天前
    你可能习惯了其他语言里的 null 可以设置为某类型的值,或者 nil 设置为指针的值,这样的语言有 java 和 golang 。

    在 Typescript 里这样是不行的,变量的类型不可以有空值,
    但是 Typescript 有联合类型,或许是你不知道联合类型这个知识点才产生了疑惑,通过 | 符号连接,你可以为一个变量声明这样的类型: `let xxx : string | number | array`表示 xxx 可能是这三种类型之一。

    有个说法是《 null ,一个十亿美元的错误》
    isa
        5
    isa  
       205 天前
    可选链 `?.` 是针对值可能为空(`null` or `undefined`)的变量的语法, 既然已经确定值类型为 `string`, 那就使用可选链的语法就是错的了
    w568w
        6
    w568w  
       205 天前
    因为 string 是指字符串。字符串就是字符串,TypeScript 的类型系统不像 Java 那样,会容忍「 null 或 undefined 也可以是字符串」。let xxx: string 你定义了变量类型但不赋值,所以报错。

    补充一下楼上说的,基本所有现代语言的类型系统都或多或少引入了代数类型(和类型又称联合类型,积类型又称元组)、泛型参数、空安全类型这些概念,学习 Typescript 的时候可以顺便学习一下。
    AV1
        7
    AV1  
       205 天前
    在 JS 里声明变量但不赋值,会默认是 undefined ,但在 TS 里,没赋值就对它的访问,就会报错。
    哪怕是 if 、typeof 、?.操作都不允许,会报 Variable 'xxx' is used before being assigned 。

    如果声明为 sting | undefined ,那就代表它在赋值之前的 undefined 值是预期行为,所以不会报错。
    Trim21
        8
    Trim21  
       205 天前   1
    @w568w #6 typescript 有 strictNullChecks 选项,其实是可以的
    UnluckyNinja
        9
    UnluckyNinja  
       205 天前
    为什么不直接把编译报的错发出来呢?
    chenluo0429
        10
    chenluo0429  
       205 天前
    第二个并不是没有赋值,而是被隐式赋值为 undefined ,因为你的类型定义允许该变量为 undefined 。
    而第一个的错误,自然是被定义为 string 类型的变量,不能被初始化为 undefined ,所以第一句只构成声明,不存在隐式 undefined 赋值。typescript 允许将声明与赋值分离,进行延迟初始化,只要你在使用前进行赋值就不会有问题。第二行在使用变量前,并没有初始化,所以才会报错。
    和?可选没关系,确定类型也可以用可选操作符的,不然做一次 if 判断,将 string | undefined 缩窄为 string 后,?难不成还得删掉
    HodorWang
        11
    HodorWang  
       205 天前
    Variable 'xxx' is used before being assigned.(2454)
    在 TypeScript 中,当你使用 let 声明一个变量但不赋值时,该变量默认为 undefined ,直到你给它赋值。
    虽然你声明了 xxx 的类型为 string ,但由于没有初始化,TypeScript 认为它可能是 undefined 。
    即使你使用了可选链操作符 ?.(它本来是用来安全地处理可能为 null 或 undefined 的值),TypeScript 仍然会警告你变量在赋值前被使用。
    wjx0912
        12
    wjx0912  
    OP
       204 天前
    基本上理解了。感谢大家
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     864 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 21:13 PVG 05:13 LAX 14:13 JFK 17:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86