问题
In TypeScript, some types are defined using extends keyof or in keyof. I have tried to understand what they mean, but so far I didn't succeed 😉
What I got is that keyof alone returns a union type which has all the names as possible values that are existent as property names on the type that you specify after keyof.
type T = keyof string;
T therefor is equivalent to startsWith | endsWith | trim | substring | ....
Is this correct?
Now, if I try to think about what extends keyof and in keyof mean, my gut feeling says the following:
extends keyofis any type that derives fromT, i.e. it has all these possible values, but maybe more.in keyofis any type that takes values fromT, but not necessarily all of them (it's possible, but maybe less).
So, from this POV extends keyof would describe a >= relation, in keyof would describe a <= relation. Is this correct? If not, what would be correct?
回答1:
For any type T, keyof T is the union of known, public property names of T.
Your assumption that keyof string yields startsWith | endsWith | trim | ... is therefor correct.
Your assumption about extends keyof is not correct though. extends, in this case, is used to define the type of a generic parameter, e.g. <T, K extends keyof T>. It has nothing to do with extending a type or inheritance, contrary to extending interfaces.
A usage of extends keyof could be the following:
interface IAnimal {
extinct: boolean;
race: string;
}
function getKeyValue<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const animal: IAnimal = {
extinct: false,
race: "dog"
};
const animalRace = getKeyValue(animal, "race"); // race is a key of IAnimal -> works
const animalAge = getKeyValue(animal, "age"); // age is not a key of IAnimal -> fails
Aside from the documentation, I found this article helpful.
Your assumption about in keyof is also incorrect. in does not describes a <= relationship, it is used when we're defining an indexer property that we want to type with specific keys.
We could for example use it to create a new type that re-maps all properties of an existing type to be optional:
type Optional<T> = { [K in keyof T]?: T[K] };
const animal: Optional<IAnimal> = {
extinct: true
};
Aside from the documentation, I once again found this article helpful.
来源:https://stackoverflow.com/questions/57337598/in-typescript-what-do-extends-keyof-and-in-keyof-mean