Comments (7)
@sindresorhus I actually thought about this a bit when writing my response. This behavior is not consistent with how Pick
or property access on union types works in TypeScript and can also be considered unintuitive:
type Pet = {
name: string;
owner: { name: 'name1' } | { foo: '' };
};
declare const pet: Pet;
function onlyNeedsOwnerName(pet: PickDeep<Pet, "owner.name">) {
...
}
onlyNeedsOwnerName(pet)
// ^ will result in an error
Again, in this case PickDeep
changes the type. Pet
is not compatible with PickDeep<Pet, "owner.name">
which some people may find surprising.
from type-fest.
Confirmed.
from type-fest.
Thanks report, but I don't think this is a bug
Let's look some cases:
case 1
type Pet = {
owner: { name: 'name1' }
| { name: 'name2' ; foo: '' };
};
type Result = PickDeep<Pet, 'owner.name'>;
PickDeep
should pick every union type, so result should indeed be
type Result = {
owner: { name: 'name1' } | { name: 'name2' }
}
case 2
type Pet = {
owner: { name: 'name1' }
| { foo: '' };
};
type Result = PickDeep<Pet, 'owner.name'>;
PickDeep
can not find key "name" in { foo: '' }
, so result is
type Result = {
owner: { name: 'name1' }
}
case 3
type Pet = {
owner: { name: 'name1' }
| null;
};
type Result = PickDeep<Pet, 'owner.name'>;
so according to case 2, PickDeep
can not find key "name" in null
, so result should be
type Result = {
owner: { name: 'name1' }
}
This is the same as the current behavior
from type-fest.
That makes sense as to why it behaves like this but to me it seems like unexpected or maybe less ergonomic behavior.
My current use case is narrowing types on function inputs like so
type Owner = {
name: string;
age: number;
}
type Pet = {
name: string;
age: number;
owner: Owner | null;
}
// I only use `name` and `owner.name`
function printGreeting(pet: PickDeep<Pet, "name" | "owner.name"> {
if (pet.owner) {
console.log(`Hi, my name is ${pet.name} and my owner is ${pet.owner.name}!`);
} else {
console.log(`Hi, my name is ${pet.name} and I'm looking for an owner!`);
}
}
Right now the function would require pet
to have an owner even though in the definition of Pet
the owner can be null
. This was unexpected because in my understanding the purpose of Pick
is to narrow a type while PickDeep
"changes" it.
from type-fest.
Okay, you convinced me. maybe we should keep union in PickDeep
to ensure type safety.
What do you think? @sindresorhus
from type-fest.
What would "case 2" become if so?
from type-fest.
What would "case 2" become if so?
that will be
type Result = {
owner: { name: 'name1' } | { foo: "" }
}
It's look like confused, I am beginning to waver on whether need do this for "type safety"
from type-fest.
Related Issues (20)
- OverrideProperties changes undefined as optional HOT 2
- Exclude / Pick type in Paths / only add leaf nodes HOT 2
- `Proposal`: add option with exclude/keep specified type on deep type HOT 5
- Unify `Get` and `Paths` / `PickDeep` etc HOT 1
- `Paths` is unable to escape dots in property names
- DistributedOmit may not need to constraint the second type argument HOT 6
- A type util to produce an alternation of function overloads. HOT 1
- PositiveIntegerString type HOT 4
- Type-fest based prelude HOT 1
- ArrayExceptLastElement type HOT 7
- Zero is not exported by ... HOT 1
- `And` and `Or` is not exported at `index.d.ts`
- ConditionalKeys does not correctly filter out `never` type HOT 3
- Paths<T> should handle recursive types
- `schema` should properly set type of objects in arrays HOT 3
- `SimplifyDeep` doesn't deep simplify lists HOT 3
- `IsStringLiteral` should be `false` for branded and tagged types
- `CamelCasedPropertiesDeep` doesn't handle `Tagged` type correctly HOT 1
- `IfxxxLiteral` (eg `IfBooleanLiteral`) are missing (only the `IsxxxLiteral` is present
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from type-fest.