Correct me if I’m wrong, but I think that from the type-system’s point of view, nothing is known about the specifics of the behavior of a function like FindFirstChildWhichIsA. It just knows that it is a function that takes in a string, and in the case that the provided string is of the singleton string type "UISiceConstraint", the function returns UISiceConstraint?. The way to work with this would be to make the result of the function call a variable and then type-narrow that with if statements like you do with the function call.
It doesn’t look like the Type System is intelligent enough or has enough information to understand that there are no possible side-effects between those two lines. It doesn’t know whether or not :FindFirstChild depends on something other than script, it doesn’t know if script itself changes, all it knows is that the return type is optional and could be nil.
The type system is correct; narrowing the return of one function call does not mean that it narrows the next. Two calls to FindFirstChild with the same argument can return different results. It would be an error if the type system suggested otherwise.
In this case it is incorrect as :FindFirstChild does not “yield” (i.e. allow the Engine to interrupt the Script and work on other tasks), and because :FindFirstChild itself does not modify any Instances, there’s never any opportunity for the state of the game to change in-between those two calls, whether through the Engine or through another Script.
What you have described is not the responsibility of the type system to determine. It checks types, not if your code can affect world state or if it yields. It’s not aware of runtime-specific features. You can perform a similar replication in TypeScript or C# (albeit C# being more forgiving and just giving a warning, rather than a compiler error). Besides other languages, what is the type system meant to do in the following example?:
if script:FindFirstChild("A") then
-- playing devil's advocate, let's say this line gives no type error
script:FindFirstChild("A").Name = "abc"
script:FindFirstChild("A").Parent = workspace
-- what do we do here? the type checker has no knowledge of the world;
-- this could be nil or it could refer to another `A`
script:FindFirstChild("A").Name = "abc"
end
As it stands, the type system is correct, and code should make use of the result and its narrowed type rather than throwing it away for a second function invocation.
I am saying that in this specific situation it is incorrect as there is no space for any of this to happen. Your original reply felt a little dismissive to the original context, not a hypothetical wherein this warning would be valid.