Whats the difference between these type annotations?

local animator: Animator = hum.Animator
and
local animator = hum.Animator :: Animator

I just noticed ive used both in different games, is there any difference?

local animator: Animator = hum.Animator → animator is an Animator, if hum.Animator is definitely an Animator
local animator = hum.Animator :: Animator → treat hum.Animator as an Animator, even if it’s not sure.

The best option is usually to not use either and just let the type checker infer the correct type.
local animator = hum.Animator
In this case, the type checker should automatically infer that animator is an Animator.

In some cases, though, you do need to use the second one, for example when you’re using :GetChildren() on an instance where you know the children are all Parts:
for _, part in folder:GetChildren() :: {Part} do ...
It’s also a good idea to specify types in function parameters

In this case, there is no difference. But there is a difference in other scenarios.

For example:

-->> does not warn, since typecasting will assume it's filled in some time in the future
local foo = {}:: {bar: number}
foo.bar = 1 --> type casting allows tables to be constructed on multiple lines

-->> warns, since typing expects the exact type immediately
local foo: {bar: number} = {}
-->> you wouldn't actually write this useless snip of code; this is just for demonstration
local function testTypecheck(unionType: string | number)
    local k: string = unionType --> warns, since "k" expects a string, but "unionType" can be a number
end

local function testTypecheck(unionType: string | number)
    local k = unionType:: string --> does not warn, since "unionType" is now interpreted as a string
end

-->> intellisense is also smart enough to notice if you typecast an impossible type
local function testTypecheck(unionType: string | number)
    local k = unionType:: boolean --> warns, since "unionType" can never be a boolean
end

You can read more about typechecking here: