為什麼 `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。
希望這有幫助
