Version: Next

Type Inference

If a variable or constant declaration is not annotated explicitly with a type, the declaration's type is inferred from the initial value.

Basic Literals​

Decimal integer literals and hex literals are inferred to type Int.

_10let a = 1_10// a has type Int_10_10let b = -45_10// b has type Int_10_10let c = 0x02_10// c has type Int

Unsigned fixed-point literals are inferred to type UFix64. Signed fixed-point literals are inferred to type Fix64.

_10let a = 1.2_10// a has type UFix64_10_10let b = -1.2_10// b has type Fix64

Similarly, for other basic literals, the types are inferred in the following manner:

Literal KindExampleInferred Type (x)
String literallet x = "hello"String
Boolean literallet x = trueBool
Nil literallet x = nilNever?

Array Literals​

Array literals are inferred based on the elements of the literal, and to be variable-size. The inferred element type is the least common super-type of all elements.

_14let integers = [1, 2]_14// integers has type [Int]_14_14let int8Array = [Int8(1), Int8(2)]_14// int8Array has type [Int8]_14_14let mixedIntegers = [UInt(65), 6, 275, Int128(13423)]_14// mixedIntegers has type [Integer]_14_14let nilableIntegers = [1, nil, 2, 3, nil]_14// nilableIntegers has type [Int?]_14_14let mixed = [1, true, 2, false]_14// mixed has type [AnyStruct]

Dictionary Literals​

Dictionary literals are inferred based on the keys and values of the literal. The inferred type of keys and values is the least common super-type of all keys and values, respectively.

_20let booleans = {_20 1: true,_20 2: false_20}_20// booleans has type {Int: Bool}_20_20let mixed = {_20 Int8(1): true,_20 Int64(2): "hello"_20}_20// mixed has type {Integer: AnyStruct}_20_20// Invalid: mixed keys_20//_20let invalidMixed = {_20 1: true,_20 false: 2_20}_20// The least common super-type of the keys is AnyStruct._20// But it is not a valid type for dictionary keys.

Ternary Expression​

Ternary expression type is inferred to be the least common super-type of the second and third operands.

_10let a = true ? 1 : 2_10// a has type Int_10_10let b = true ? 1 : nil_10// b has type Int?_10_10let c = true ? 5 : (false ? "hello" : nil)_10// c has type AnyStruct

Functions​

Functions are inferred based on the parameter types and the return type.

_10let add = (a: Int8, b: Int8): Int {_10 return a + b_10}_10_10// add has type fun(Int8, Int8): Int

Type inference is performed for each expression / statement, and not across statements.

Ambiguities​

There are cases where types cannot be inferred. In these cases explicit type annotations are required.

_10// Invalid: not possible to infer type based on array literal's elements._10//_10let array = []_10_10// Instead, specify the array type and the concrete element type, e.g. Int._10//_10let array: [Int] = []_10_10// Or, use a simple-cast to annotate the expression with a type._10let array = [] as [Int]
_11// Invalid: not possible to infer type based on dictionary literal's keys and values._11//_11let dictionary = {}_11_11// Instead, specify the dictionary type and the concrete key_11// and value types, e.g. String and Int._11//_11let dictionary: {String: Int} = {}_11_11// Or, use a simple-cast to annotate the expression with a type._11let dictionary = {} as {String: Int}