Giter Club home page Giter Club logo

Comments (7)

relsunkaev avatar relsunkaev commented on June 16, 2024 1

@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.

sindresorhus avatar sindresorhus commented on June 16, 2024

Confirmed.

Playground: https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbwArAMYGsAiBTbYC+cAZlBCHAOQwCeY2AtEdgM4wUDcAUJzXXAPIB3AHbYocALyJOcOMICGIbAC44rKMGEBzLrPlaVcgK4gARmK74uPWtjhJs8KQhlzFh9Zp2v9h4SfMoXTgIETFVIVFxAB9jABs4y2teOyIICEl7NCxcMAAeBxgAGjgAIgUlUrhY0tCogDoK7FKAPnYgA

from type-fest.

Emiyaaaaa avatar Emiyaaaaa commented on June 16, 2024

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.

relsunkaev avatar relsunkaev commented on June 16, 2024

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.

Emiyaaaaa avatar Emiyaaaaa commented on June 16, 2024

Okay, you convinced me. maybe we should keep union in PickDeep to ensure type safety.

What do you think? @sindresorhus

from type-fest.

sindresorhus avatar sindresorhus commented on June 16, 2024

What would "case 2" become if so?

from type-fest.

Emiyaaaaa avatar Emiyaaaaa commented on June 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.