diff --git src/wp-includes/user.php src/wp-includes/user.php
index e602a3e..4e0f385 100644
--- src/wp-includes/user.php
+++ src/wp-includes/user.php
@@ -555,7 +555,11 @@ class WP_User_Query {
 	 *                                         of fields. Accepts 'ID', 'display_name', 'login', 'nicename', 'email',
 	 *                                         'url', 'registered'. Use 'all' for all fields and 'all_with_meta' to
 	 *                                         include meta fields. Default 'all'.
-	 *     @type string       $who             Type of users to query. Accepts 'authors'. Default empty (all users).
+	 *     @type string       $who             Type of users to query. Accepts 'authors', 'public_author'. Default empty (all users).
+	 *     @type bool|array   $has_published_posts If the user has published posts in the specified post type(s). Accepts `true`
+	 *                                             to indicate all public post types; `false` to indicate the user has published in
+	 *                                             non-public post types; or `array( $post_type )` for users who have published posts
+	 *                                             in the specified post types.
 	 * }
 	 */
 	public function prepare_query( $query = array() ) {
@@ -638,6 +642,22 @@ class WP_User_Query {
 			$qv['blog_id'] = $blog_id = 0; // Prevent extra meta query
 		}
 
+		if ( isset( $qv['has_published_posts'] ) && $blog_id ) {
+
+			if ( true === $qv['has_published_posts'] ) {
+				$post_types = get_post_types( array( 'public' => true ) );
+				$operator = 'IN';
+			} else if ( false === $qv['has_published_posts'] ) {
+				$post_types = get_post_types( array( 'public' => true ) );
+				$operator = 'NOT IN';
+			} else if ( is_array( $qv['has_published_posts'] ) ) {
+				$post_types = $qv['has_published_posts'];
+				$operator = 'IN';
+			}
+
+			$this->query_where .= " AND $wpdb->users.ID IN ( SELECT DISTINCT $wpdb->posts.post_author FROM $wpdb->posts WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type " . $operator . " ( '" . join( "', '", $post_types ) . "' ) )";
+		}
+
 		// Meta query.
 		$this->meta_query = new WP_Meta_Query();
 		$this->meta_query->parse_query_vars( $qv );
diff --git tests/phpunit/tests/user/query.php tests/phpunit/tests/user/query.php
index 9abf99d..11d5d8c 100644
--- tests/phpunit/tests/user/query.php
+++ tests/phpunit/tests/user/query.php
@@ -686,4 +686,60 @@ class Tests_User_Query extends WP_UnitTestCase {
 		$this->assertContains( $users[1], $found );
 		$this->assertNotContains( $users[2], $found );
 	}
+
+	public function test_has_published_posts() {
+
+		$users = $this->factory->user->create_many( 3 );
+
+		$this->factory->post->create( array( 'post_author' => $users[0], 'post_status' => 'publish', 'post_type' => 'post' ) );
+		$this->factory->post->create( array( 'post_author' => $users[1], 'post_status' => 'publish', 'post_type' => 'post' ) );
+
+		$q = new WP_User_Query( array(
+			'has_published_posts' => true,
+		) );
+
+		$found = wp_list_pluck( $q->get_results(), 'ID' );
+
+		$this->assertEquals( 2, $q->get_total() );
+
+		$this->assertContains( $users[0], $found );
+		$this->assertContains( $users[1], $found );
+	}
+
+	public function test_has_published_posts_in_non_public_post_types() {
+
+		$users = $this->factory->user->create_many( 3 );
+
+		$this->factory->post->create( array( 'post_author' => $users[0], 'post_status' => 'publish', 'post_type' => 'revision' ) );
+		$this->factory->post->create( array( 'post_author' => $users[1], 'post_status' => 'publish', 'post_type' => 'revision' ) );
+
+		$q = new WP_User_Query( array(
+			'has_published_posts' => false,
+		) );
+
+		$found = wp_list_pluck( $q->get_results(), 'ID' );
+
+		$this->assertEquals( 2, $q->get_total() );
+
+		$this->assertContains( $users[0], $found );
+		$this->assertContains( $users[1], $found );
+	}
+
+	public function test_has_published_posts_in_custom_post_types() {
+
+		$users = $this->factory->user->create_many( 3 );
+
+		$this->factory->post->create( array( 'post_author' => $users[0], 'post_status' => 'publish', 'post_type' => 'post' ) );
+		$this->factory->post->create( array( 'post_author' => $users[1], 'post_status' => 'publish', 'post_type' => 'revision' ) );
+
+		$q = new WP_User_Query( array(
+			'has_published_posts' => array( 'post' ),
+		) );
+
+		$found = wp_list_pluck( $q->get_results(), 'ID' );
+
+		$this->assertEquals( 1, $q->get_total() );
+
+		$this->assertContains( $users[0], $found );
+	}
 }
