網站搜尋

為什麼 `declare const foo=3` 在 TypeScript 中是合法的?


我正在嘗試撰寫一些 TypeScript 宣告檔,然後發現宣告一個 const 並賦值是合法的。

declare const foo = 1;        // This is legal
declare const bar = 'b';      // This is legal too
declare const baz = () => {}; // ERROR: A 'const' initializer in an ambient context must be a string or numeric literal.

declare var foo1 = 1;      // ERROR: Initializers are not allowed in ambient contexts.
declare let bar1 = 2;      // ERROR: Initializers are not allowed in ambient contexts.
declare function baz1() {} // ERROR: An implementation cannot be declared in ambient contexts.

依我理解,在宣告語句中指定值應該是違法的。

我知道在 const 聲明中,foo 的類型可以被推斷為 1,但是,declare const foo: 1 難道不是更好的聲明嗎?

為什麼 TypeScript 允許 declare const 被賦值?

答案#1

我無法確定地告訴你它為什麼會是這樣,但這是我的理解。我不認為官方文件中有明確描述這一點,但這對我來說似乎最合理。考慮到規範指出這樣的賦值是不可能的,這在我看來似乎是編譯器的一個錯誤。

AmbientDeclaration:
   declare AmbientVariableDeclaration

AmbientVariableDeclaration:
   var AmbientBindingList ;
   let AmbientBindingList ;
   const AmbientBindingList ;

AmbientBindingList:
   AmbientBinding
   AmbientBindingList , AmbientBinding

AmbientBinding:
   BindingIdentifier TypeAnnotation_opt

當你 宣告 一個變數時,你只是向編譯器聲明某個使用該名稱的符號應被假定存在。實際的實現將在其他地方提供。對於該宣告實際上不會產生任何東西。

通常當你使用 declare 時,你也會提供一個類型。在這個語境中,可以使用數字或字串,因為它們都是字面量、不可變且有效的常數值,編譯器可以推斷該符號應該是什麼類型。否則,你提供的值不會有其他效果。

我同意這很令人困惑,如果不允許這個作業,可能會更合理。在環境上下文中,你只是提供關於應該可用的符號和類型的信息。

至於為什麼其他方法行不通:

  • baz - 你正在嘗試將非常數值分配給一個宣告
  • foo1, bar1 - 你正在嘗試將非固定值指派給非固定變數
  • baz1 - 你正在宣告一個具有某種實作(什麼也不做)的函數。要宣告一個函數,你必須使用沒有本體的函數語法,也就是一個「原型」。

    declare function baz(): void; // function baz returns void
    

答案#2

首先,宣告 accept 變數的值,參考 https://www.typescriptlang.org/docs/handbook/declaration-merging.html

其次:1 定義的是 foo 的類型,而不是 foo 的值,所以你不能使用它,因為它是用來指出 foo 只能是 1,而不是將 1 賦值給 foo。

希望這有幫助