That's not the meaning of dependent types, and dependent type checkers don't require runtime information.
The value does not exist during compilation. AFAIKT dependent type are used mostly during executable proof checkers to verify claims on the value-dependent types. So maybe using the term runtime is a bit to specific, but you do not have values (except literals) during typescript execution phase.
The gist of how it works is so:
createEmptyIntList() => List<size=0, content=int> {...}
push(List<size=a, content=b>) => List<size=a+1, content=b> {...}
firstElement(List<size=a, content=b> | a > 0) => b {...}
In this example, you don't need to know runtime values, you need to know that you can safely get the first element. For that, you just need to know that something has been pushed at least once in the list.Since push returns a type that is different from createEmptyList, your typesystem has this information.
type Z = []["length"]
type One = [0]["length"]
type Two = [0,0]["length"]